mirror of
https://github.com/hanzoai/visor.git
synced 2026-09-24 17:04:14 +00:00
bpf(2): return EPERM for unsupported BPF commands without CAP_SYS_ADMIN.
Matches Linux more closely. PiperOrigin-RevId: 958490279
This commit is contained in:
committed by
gVisor bot
parent
86be803f8a
commit
9f46059b08
@@ -334,27 +334,32 @@ func Bpf(t *kernel.Task, sysno uintptr, args arch.SyscallArguments) (uintptr, *k
|
||||
return 0, nil, err
|
||||
}
|
||||
|
||||
switch cmd {
|
||||
case linux.BPF_PROG_LOAD:
|
||||
fd, err := bpfProgLoad(t, attr.(*linux.BPFAttrProgLoad))
|
||||
switch attr := attr.(type) {
|
||||
case *linux.BPFAttrProgLoad:
|
||||
fd, err := bpfProgLoad(t, attr)
|
||||
return fd, nil, err
|
||||
|
||||
case linux.BPF_PROG_QUERY:
|
||||
attr := attr.(*linux.BPFAttrProgQuery)
|
||||
case *linux.BPFAttrProgQuery:
|
||||
size := min(int(size), attr.SizeBytes())
|
||||
ret, err := bpfProgQuery(t, attr, attrAddr, size)
|
||||
return ret, nil, err
|
||||
|
||||
case linux.BPF_PROG_ATTACH:
|
||||
ret, err := bpfProgAttach(t, attr.(*linux.BPFAttrProgAttach))
|
||||
case *linux.BPFAttrProgAttach:
|
||||
ret, err := bpfProgAttach(t, attr)
|
||||
return ret, nil, err
|
||||
|
||||
default:
|
||||
// Unsupported command
|
||||
// Unsupported command.
|
||||
if !t.HasRootCapability(linux.CAP_SYS_ADMIN) {
|
||||
return 0, nil, linuxerr.EPERM
|
||||
}
|
||||
return 0, nil, linuxerr.EINVAL
|
||||
}
|
||||
}
|
||||
|
||||
// copyInBPFAttr fetches and returns a BPFAttr of the type specified by cmd from userspace.
|
||||
//
|
||||
// If cmd is invalid or unsupported, the nil BPFAttr is returned (along with no error).
|
||||
func copyInBPFAttr(t *kernel.Task, cmd int32, addr hostarch.Addr, size int) (linux.BPFAttr, error) {
|
||||
// Invalid size. Negative size here would indicate overflow
|
||||
if size < 0 || size > hostarch.PageSize {
|
||||
@@ -370,7 +375,7 @@ func copyInBPFAttr(t *kernel.Task, cmd int32, addr hostarch.Addr, size int) (lin
|
||||
case linux.BPF_PROG_ATTACH:
|
||||
bpfAttr = &linux.BPFAttrProgAttach{}
|
||||
default:
|
||||
return nil, linuxerr.EINVAL
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// Copy in the valid fields of the BPFAttr structure
|
||||
|
||||
@@ -623,12 +623,27 @@ TEST_F(EbpfTest, QueryRequiresCapability) {
|
||||
|
||||
// bpf(2) argument handling
|
||||
|
||||
TEST_F(EbpfTest, InvalidCommandFails) {
|
||||
TEST_F(EbpfTest, UnimplementedCommandWithCapFails) {
|
||||
SKIP_IF(!IsRunningOnGvisor());
|
||||
|
||||
// Unimplemented cmd with capabilities should give EINVAL.
|
||||
BpfAttrProgAttach attr = {};
|
||||
EXPECT_THAT(bpf(0x7fffffff, &attr, sizeof(attr)),
|
||||
EXPECT_THAT(bpf(BPF_MAP_CREATE, &attr, sizeof(attr)),
|
||||
SyscallFailsWithErrno(EINVAL));
|
||||
}
|
||||
|
||||
TEST_F(EbpfTest, UnimplementedCommandWithoutCapFails) {
|
||||
SKIP_IF(!IsRunningOnGvisor());
|
||||
|
||||
AutoCapability cap_sys_admin(CAP_SYS_ADMIN, false);
|
||||
AutoCapability cap_bpf(CAP_BPF, false);
|
||||
|
||||
// Unimplemented cmd without capabilities should give EPERM.
|
||||
BpfAttrProgAttach attr = {};
|
||||
EXPECT_THAT(bpf(BPF_MAP_CREATE, &attr, sizeof(attr)),
|
||||
SyscallFailsWithErrno(EPERM));
|
||||
}
|
||||
|
||||
TEST_F(EbpfTest, AttrSizeTooLargeFails) {
|
||||
BpfAttrProgAttach attr = {};
|
||||
EXPECT_THAT(bpf(BPF_PROG_ATTACH, &attr, 1 << 20),
|
||||
|
||||
Reference in New Issue
Block a user