@@ -416,9 +416,22 @@ func newProgramInfoFromFd(fd *sys.FD) (*ProgramInfo, error) {
416416
417417 if info .XlatedProgLen > 0 {
418418 pi .insns = make ([]byte , info .XlatedProgLen )
419+ var info2 sys.ProgInfo
419420 info2 .XlatedProgLen = info .XlatedProgLen
420421 info2 .XlatedProgInsns = sys .SlicePointer (pi .insns )
421- makeSecondCall = true
422+
423+ // Linux kernel has a bug(?): if xlated_prog_len is specified and access is denied
424+ // by kernel.kptr_restrict or net.core.bpf_jit_harden sysctls, the syscall doesn't only
425+ // skip the xlated program's bytes, but other information as well.
426+ // See handling of xlated_prog_insns in bpf_prog_get_info_by_fd in kernel/bpf/syscall.c.
427+ // To avoid skipping other information, we specify xlated_prog_len in a separate syscall.
428+ if err := sys .ObjInfo (fd , & info2 ); err != nil {
429+ return nil , err
430+ }
431+ if info2 .XlatedProgInsns .IsNil () {
432+ pi .restricted = true
433+ pi .insns = nil
434+ }
422435 }
423436
424437 if info .NrLineInfo > 0 {
@@ -477,14 +490,13 @@ func newProgramInfoFromFd(fd *sys.FD) (*ProgramInfo, error) {
477490 if err := sys .ObjInfo (fd , & info2 ); err != nil {
478491 return nil , err
479492 }
480- }
481-
482- if info .XlatedProgLen > 0 && info2 .XlatedProgInsns .IsNil () {
483- pi .restricted = true
484- pi .insns = nil
485- pi .lineInfos = nil
486- pi .funcInfos = nil
487- pi .jitedInfo = programJitedInfo {}
493+ if info .JitedProgLen > 0 && info2 .JitedProgInsns .IsNil () {
494+ // JIT information is not available due to kernel.kptr_restrict
495+ pi .jitedInfo .lineInfos = nil
496+ pi .jitedInfo .ksyms = nil
497+ pi .jitedInfo .insns = nil
498+ pi .jitedInfo .funcLens = nil
499+ }
488500 }
489501
490502 return & pi , nil
@@ -581,10 +593,6 @@ var ErrRestrictedKernel = internal.ErrRestrictedKernel
581593// ErrNotSupported if the program was created without BTF or if the kernel
582594// doesn't support the field.
583595func (pi * ProgramInfo ) LineInfos () (btf.LineOffsets , error ) {
584- if pi .restricted {
585- return nil , fmt .Errorf ("line infos: %w" , ErrRestrictedKernel )
586- }
587-
588596 if len (pi .lineInfos ) == 0 {
589597 return nil , fmt .Errorf ("insufficient permissions or unsupported kernel: %w" , ErrNotSupported )
590598 }
@@ -708,10 +716,6 @@ func (pi *ProgramInfo) Instructions() (asm.Instructions, error) {
708716//
709717// Available from 4.13. Reading this metadata requires CAP_BPF or equivalent.
710718func (pi * ProgramInfo ) JitedSize () (uint32 , error ) {
711- if pi .restricted {
712- return 0 , fmt .Errorf ("jited size: %w" , ErrRestrictedKernel )
713- }
714-
715719 if pi .jitedSize == 0 {
716720 return 0 , fmt .Errorf ("insufficient permissions, unsupported kernel, or JIT compiler disabled: %w" , ErrNotSupported )
717721 }
@@ -832,10 +836,6 @@ func (pi *ProgramInfo) JitedFuncLens() ([]uint32, bool) {
832836// ErrNotSupported if the program was created without BTF or if the kernel
833837// doesn't support the field.
834838func (pi * ProgramInfo ) FuncInfos () (btf.FuncOffsets , error ) {
835- if pi .restricted {
836- return nil , fmt .Errorf ("func infos: %w" , ErrRestrictedKernel )
837- }
838-
839839 if len (pi .funcInfos ) == 0 {
840840 return nil , fmt .Errorf ("insufficient permissions or unsupported kernel: %w" , ErrNotSupported )
841841 }
0 commit comments