Skip to content

Commit

Permalink
syscalls: do not conceal BPF_PROG_* syscall errors
Browse files Browse the repository at this point in the history
The error wrapping code for BPF_PROG_* syscall-related errors would mask
the true source of all underlying syscall errors, which meant that you
couldn't detect several fairly important cases (such as -EACESS and
-EPERM). It seems that this behaviour wasn't intentional (prior to
commit de57e91, the behaviour was to bubble up the syscall error)
and the similar wrapping of BPF_MAP_* errors did bubble up the syscall
error too.

This is needed for runc to be able to detect permission errors due to
SELinux labels blocking certain operations (mainly NewProgramFromID),
and unifies the behaviour for BPF_PROG_* and BPF_MAP_* syscalls.

It turns out that wrapMapError doesn't actually wrap the either error,
but lmb said they will come up with a better long term solution, so
leave this alone for now.

Fixes: de57e91 ("Add *GetNextID")
Signed-off-by: Aleksa Sarai <[email protected]>
  • Loading branch information
cyphar committed Jul 2, 2021
1 parent 37b4af7 commit 23adcaa
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 3 deletions.
5 changes: 2 additions & 3 deletions syscalls.go
Original file line number Diff line number Diff line change
Expand Up @@ -357,10 +357,9 @@ func wrapObjError(err error) error {
return nil
}
if errors.Is(err, unix.ENOENT) {
return fmt.Errorf("%w", ErrNotExist)
err = ErrNotExist
}

return errors.New(err.Error())
return fmt.Errorf("%w", err)
}

func wrapMapError(err error) error {
Expand Down
18 changes: 18 additions & 0 deletions syscalls_test.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
package ebpf

import (
"errors"
"strings"
"testing"

"github.com/cilium/ebpf/internal/testutils"
"golang.org/x/sys/unix"
)

func TestObjNameCharacters(t *testing.T) {
Expand All @@ -23,6 +25,22 @@ func TestObjNameCharacters(t *testing.T) {
}
}

func TestWrapObjError(t *testing.T) {
customError := errors.New("custom error for test")
for inErr, outErr := range map[error]error{
unix.ENOENT: ErrNotExist,
unix.EPERM: unix.EPERM,
unix.EACCES: unix.EACCES,
unix.ENOANO: unix.ENOANO, // dummy error -- never actually returned
customError: customError,
} {
gotErr := wrapObjError(inErr)
if !errors.Is(gotErr, outErr) {
t.Errorf("wrapObjError(%v) doesn't wrap %v: got %v", inErr, outErr, gotErr)
}
}
}

func TestHaveBatchAPI(t *testing.T) {
testutils.CheckFeatureTest(t, haveBatchAPI)
}
Expand Down

0 comments on commit 23adcaa

Please sign in to comment.