mirror of
https://github.com/netbirdio/gvisor.git
synced 2026-05-22 17:12:49 -07:00
hostinet: Support ping and raw sockets.
PiperOrigin-RevId: 513902015
This commit is contained in:
committed by
gVisor bot
parent
da3c2bbb82
commit
f37b20c011
@@ -286,8 +286,8 @@ swgso-tests: load-basic $(RUNTIME_BIN)
|
||||
.PHONY: swgso-tests
|
||||
|
||||
hostnet-tests: load-basic $(RUNTIME_BIN)
|
||||
@$(call install_runtime,$(RUNTIME),--network=host)
|
||||
@$(call test_runtime,$(RUNTIME),--test_env=CHECKPOINT=false --test_env=HOSTNET=true $(INTEGRATION_TARGETS))
|
||||
@$(call install_runtime,$(RUNTIME),--network=host --net-raw)
|
||||
@$(call test_runtime,$(RUNTIME),--test_env=TEST_CHECKPOINT=false --test_env=TEST_HOSTNET=true --test_env=TEST_NET_RAW=true $(INTEGRATION_TARGETS))
|
||||
.PHONY: hostnet-tests
|
||||
|
||||
kvm-tests: load-basic $(RUNTIME_BIN)
|
||||
@@ -311,7 +311,7 @@ iptables-tests: load-iptables $(RUNTIME_BIN)
|
||||
@# FIXME(b/218923513): Need to fix permissions issues.
|
||||
@#$(call test,--test_env=RUNTIME=runc //test/iptables:iptables_test)
|
||||
@$(call install_runtime,$(RUNTIME),--net-raw)
|
||||
@$(call test_runtime,$(RUNTIME),//test/iptables:iptables_test)
|
||||
@$(call test_runtime,$(RUNTIME),--test_env=TEST_NET_RAW=true //test/iptables:iptables_test)
|
||||
.PHONY: iptables-tests
|
||||
|
||||
packetdrill-tests: load-packetdrill $(RUNTIME_BIN)
|
||||
|
||||
@@ -603,3 +603,6 @@ const SO_ACCEPTCON = 1 << 16
|
||||
type ICMP6Filter struct {
|
||||
Filter [8]uint32
|
||||
}
|
||||
|
||||
// SizeOfICMP6Filter is the size of ICMP6Filter struct.
|
||||
var SizeOfICMP6Filter = uint32((*ICMP6Filter)(nil).SizeBytes())
|
||||
|
||||
@@ -34,6 +34,7 @@ go_library(
|
||||
"//pkg/sentry/hostfd",
|
||||
"//pkg/sentry/inet",
|
||||
"//pkg/sentry/kernel",
|
||||
"//pkg/sentry/kernel/auth",
|
||||
"//pkg/sentry/kernel/time",
|
||||
"//pkg/sentry/socket",
|
||||
"//pkg/sentry/socket/control",
|
||||
|
||||
@@ -29,6 +29,7 @@ import (
|
||||
"gvisor.dev/gvisor/pkg/sentry/fsimpl/sockfs"
|
||||
"gvisor.dev/gvisor/pkg/sentry/hostfd"
|
||||
"gvisor.dev/gvisor/pkg/sentry/kernel"
|
||||
"gvisor.dev/gvisor/pkg/sentry/kernel/auth"
|
||||
ktime "gvisor.dev/gvisor/pkg/sentry/kernel/time"
|
||||
"gvisor.dev/gvisor/pkg/sentry/socket"
|
||||
"gvisor.dev/gvisor/pkg/sentry/socket/control"
|
||||
@@ -66,6 +67,21 @@ var AllowedSocketTypes = []AllowedSocketType{
|
||||
|
||||
{unix.AF_INET6, unix.SOCK_STREAM, unix.IPPROTO_TCP},
|
||||
{unix.AF_INET6, unix.SOCK_DGRAM, unix.IPPROTO_UDP},
|
||||
{unix.AF_INET6, unix.SOCK_DGRAM, unix.IPPROTO_ICMPV6},
|
||||
}
|
||||
|
||||
// AllowedRawSocketTypes are the socket types which are supported by hostinet
|
||||
// with raw sockets enabled.
|
||||
var AllowedRawSocketTypes = []AllowedSocketType{
|
||||
{unix.AF_INET, unix.SOCK_RAW, unix.IPPROTO_RAW},
|
||||
{unix.AF_INET, unix.SOCK_RAW, unix.IPPROTO_TCP},
|
||||
{unix.AF_INET, unix.SOCK_RAW, unix.IPPROTO_UDP},
|
||||
{unix.AF_INET, unix.SOCK_RAW, unix.IPPROTO_ICMP},
|
||||
|
||||
{unix.AF_INET6, unix.SOCK_RAW, unix.IPPROTO_RAW},
|
||||
{unix.AF_INET6, unix.SOCK_RAW, unix.IPPROTO_TCP},
|
||||
{unix.AF_INET6, unix.SOCK_RAW, unix.IPPROTO_UDP},
|
||||
{unix.AF_INET6, unix.SOCK_RAW, unix.IPPROTO_ICMPV6},
|
||||
}
|
||||
|
||||
// Socket implements socket.Socket (and by extension, vfs.FileDescriptionImpl)
|
||||
@@ -185,16 +201,24 @@ type socketProvider struct {
|
||||
// Socket implements socket.Provider.Socket.
|
||||
func (p *socketProvider) Socket(t *kernel.Task, stypeflags linux.SockType, protocol int) (*vfs.FileDescription, *syserr.Error) {
|
||||
// Check that we are using the host network stack.
|
||||
stack := t.NetworkContext()
|
||||
if stack == nil {
|
||||
netCtx := t.NetworkContext()
|
||||
if netCtx == nil {
|
||||
return nil, nil
|
||||
}
|
||||
if _, ok := stack.(*Stack); !ok {
|
||||
stack, ok := netCtx.(*Stack)
|
||||
if !ok {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
stype := stypeflags & linux.SOCK_TYPE_MASK
|
||||
|
||||
// Raw sockets require CAP_NET_RAW.
|
||||
if stype == linux.SOCK_RAW {
|
||||
if creds := auth.CredentialsFromContext(t); !creds.HasCapability(linux.CAP_NET_RAW) {
|
||||
return nil, syserr.ErrNotPermitted
|
||||
}
|
||||
}
|
||||
|
||||
// Convert generic IPPROTO_IP protocol to the actual protocol depending
|
||||
// on family and type.
|
||||
if protocol == linux.IPPROTO_IP && (p.family == linux.AF_INET || p.family == linux.AF_INET6) {
|
||||
@@ -208,7 +232,7 @@ func (p *socketProvider) Socket(t *kernel.Task, stypeflags linux.SockType, proto
|
||||
|
||||
// Validate the socket based on family, type, and protocol.
|
||||
var supported bool
|
||||
for _, allowed := range AllowedSocketTypes {
|
||||
for _, allowed := range stack.allowedSocketTypes {
|
||||
if p.family == allowed.Family && int(stype) == allowed.Type && protocol == allowed.Protocol {
|
||||
supported = true
|
||||
break
|
||||
@@ -222,7 +246,8 @@ func (p *socketProvider) Socket(t *kernel.Task, stypeflags linux.SockType, proto
|
||||
|
||||
// Conservatively ignore all flags specified by the application and add
|
||||
// SOCK_NONBLOCK since socketOperations requires it.
|
||||
fd, err := unix.Socket(p.family, int(stype)|unix.SOCK_NONBLOCK|unix.SOCK_CLOEXEC, protocol)
|
||||
st := int(stype) | unix.SOCK_NONBLOCK | unix.SOCK_CLOEXEC
|
||||
fd, err := unix.Socket(p.family, st, protocol)
|
||||
if err != nil {
|
||||
return nil, syserr.FromError(err)
|
||||
}
|
||||
|
||||
@@ -59,6 +59,7 @@ type SockOpt struct {
|
||||
var SockOpts = []SockOpt{
|
||||
{linux.SOL_IP, linux.IP_ADD_MEMBERSHIP, 0, false, true},
|
||||
{linux.SOL_IP, linux.IP_DROP_MEMBERSHIP, 0, false, true},
|
||||
{linux.SOL_IP, linux.IP_HDRINCL, sizeofInt32, true, true},
|
||||
{linux.SOL_IP, linux.IP_MULTICAST_IF, uint64(linux.SizeOfInetAddr), true, true},
|
||||
{linux.SOL_IP, linux.IP_MULTICAST_LOOP, 0 /* can be 32-bit int or 8-bit uint */, true, true},
|
||||
{linux.SOL_IP, linux.IP_MULTICAST_TTL, 0 /* can be 32-bit int or 8-bit uint */, true, true},
|
||||
@@ -70,6 +71,7 @@ var SockOpts = []SockOpt{
|
||||
{linux.SOL_IP, linux.IP_TOS, 0 /* Can be 32, 16, or 8 bits */, true, true},
|
||||
{linux.SOL_IP, linux.IP_TTL, sizeofInt32, true, true},
|
||||
|
||||
{linux.SOL_IPV6, linux.IPV6_CHECKSUM, sizeofInt32, true, true},
|
||||
{linux.SOL_IPV6, linux.IPV6_MULTICAST_HOPS, sizeofInt32, true, true},
|
||||
{linux.SOL_IPV6, linux.IPV6_RECVERR, sizeofInt32, true, true},
|
||||
{linux.SOL_IPV6, linux.IPV6_RECVHOPLIMIT, sizeofInt32, true, true},
|
||||
@@ -81,6 +83,7 @@ var SockOpts = []SockOpt{
|
||||
{linux.SOL_IPV6, linux.IPV6_V6ONLY, sizeofInt32, true, true},
|
||||
|
||||
{linux.SOL_SOCKET, linux.SO_ACCEPTCONN, sizeofInt32, true, true},
|
||||
{linux.SOL_SOCKET, linux.SO_BINDTODEVICE, 0, true, true},
|
||||
{linux.SOL_SOCKET, linux.SO_BROADCAST, sizeofInt32, true, true},
|
||||
{linux.SOL_SOCKET, linux.SO_ERROR, sizeofInt32, true, false},
|
||||
{linux.SOL_SOCKET, linux.SO_KEEPALIVE, sizeofInt32, true, true},
|
||||
@@ -111,6 +114,8 @@ var SockOpts = []SockOpt{
|
||||
{linux.SOL_TCP, linux.TCP_SYNCNT, sizeofInt32, true, true},
|
||||
{linux.SOL_TCP, linux.TCP_USER_TIMEOUT, sizeofInt32, true, true},
|
||||
{linux.SOL_TCP, linux.TCP_WINDOW_CLAMP, sizeofInt32, true, true},
|
||||
|
||||
{linux.SOL_ICMPV6, linux.ICMPV6_FILTER, uint64(linux.SizeOfICMP6Filter), true, true},
|
||||
}
|
||||
|
||||
// sockOptMap is a map of {level, name} -> SockOpts. It is an optimization for
|
||||
|
||||
@@ -64,6 +64,8 @@ type Stack struct {
|
||||
tcpSACKEnabled bool
|
||||
netDevFile *os.File
|
||||
netSNMPFile *os.File
|
||||
// allowedSocketTypes is the list of allowed socket types
|
||||
allowedSocketTypes []AllowedSocketType
|
||||
}
|
||||
|
||||
// Destroy implements inet.Stack.Destroy.
|
||||
@@ -79,7 +81,7 @@ func NewStack() *Stack {
|
||||
}
|
||||
|
||||
// Configure sets up the stack using the current state of the host network.
|
||||
func (s *Stack) Configure() error {
|
||||
func (s *Stack) Configure(allowRawSockets bool) error {
|
||||
if err := addHostInterfaces(s); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -127,6 +129,11 @@ func (s *Stack) Configure() error {
|
||||
s.netSNMPFile = f
|
||||
}
|
||||
|
||||
s.allowedSocketTypes = AllowedSocketTypes
|
||||
if allowRawSockets {
|
||||
s.allowedSocketTypes = append(s.allowedSocketTypes, AllowedRawSocketTypes...)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -101,6 +101,7 @@ var SocketFlagSet = abi.FlagSet{
|
||||
var ipProtocol = abi.ValueSet{
|
||||
linux.IPPROTO_IP: "IPPROTO_IP",
|
||||
linux.IPPROTO_ICMP: "IPPROTO_ICMP",
|
||||
linux.IPPROTO_ICMPV6: "IPPROTO_ICMPV6",
|
||||
linux.IPPROTO_IGMP: "IPPROTO_IGMP",
|
||||
linux.IPPROTO_IPIP: "IPPROTO_IPIP",
|
||||
linux.IPPROTO_TCP: "IPPROTO_TCP",
|
||||
|
||||
@@ -49,13 +49,16 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
checkpoint = flag.Bool("checkpoint", BoolFromEnv("CHECKPOINT", true), "control checkpoint/restore support")
|
||||
partition = flag.Int("partition", IntFromEnv("PARTITION", 1), "partition number, this is 1-indexed")
|
||||
totalPartitions = flag.Int("total_partitions", IntFromEnv("TOTAL_PARTITIONS", 1), "total number of partitions")
|
||||
isRunningWithHostNet = flag.Bool("hostnet", BoolFromEnv("HOSTNET", false), "whether test is running with hostnet")
|
||||
runscPath = flag.String("runsc", os.Getenv("RUNTIME"), "path to runsc binary")
|
||||
// Note: flag overlay is already taken by runsc.
|
||||
partition = flag.Int("partition", IntFromEnv("PARTITION", 1), "partition number, this is 1-indexed")
|
||||
totalPartitions = flag.Int("total_partitions", IntFromEnv("TOTAL_PARTITIONS", 1), "total number of partitions")
|
||||
runscPath = flag.String("runsc", os.Getenv("RUNTIME"), "path to runsc binary")
|
||||
|
||||
// Flags controlling features for sandbox under test, prefixed with
|
||||
// "test-" to avoid potential conflicts with runsc flags.
|
||||
checkpointSupported = flag.Bool("test-checkpoint", BoolFromEnv("TEST_CHECKPOINT", true), "control checkpoint/restore support")
|
||||
isRunningWithOverlay = flag.Bool("test-overlay", BoolFromEnv("TEST_OVERLAY", false), "whether test is running with --overlay2")
|
||||
isRunningWithNetRaw = flag.Bool("test-net-raw", BoolFromEnv("TEST_NET_RAW", false), "whether test is running with raw socket support")
|
||||
isRunningWithHostNet = flag.Bool("test-hostnet", BoolFromEnv("TEST_HOSTNET", false), "whether test is running with hostnet")
|
||||
|
||||
// TestEnvSupportsRawSockets indicates whether a test sandbox can
|
||||
// create raw sockets.
|
||||
@@ -117,7 +120,7 @@ func DurationFromEnv(name string, def time.Duration) time.Duration {
|
||||
|
||||
// IsCheckpointSupported returns the relevant command line flag.
|
||||
func IsCheckpointSupported() bool {
|
||||
return *checkpoint
|
||||
return *checkpointSupported
|
||||
}
|
||||
|
||||
// IsRunningWithHostNet returns the relevant command line flag.
|
||||
@@ -125,6 +128,11 @@ func IsRunningWithHostNet() bool {
|
||||
return *isRunningWithHostNet
|
||||
}
|
||||
|
||||
// IsRunningWithNetRaw returns the relevant command line flag.
|
||||
func IsRunningWithNetRaw() bool {
|
||||
return *isRunningWithNetRaw
|
||||
}
|
||||
|
||||
// IsRunningWithOverlay returns the relevant command line flag.
|
||||
func IsRunningWithOverlay() bool {
|
||||
return *isRunningWithOverlay
|
||||
|
||||
@@ -22,7 +22,7 @@ import (
|
||||
)
|
||||
|
||||
// hostInetFilters contains syscalls that are needed by sentry/socket/hostinet.
|
||||
func hostInetFilters() seccomp.SyscallRules {
|
||||
func hostInetFilters(allowRawSockets bool) seccomp.SyscallRules {
|
||||
rules := seccomp.SyscallRules{
|
||||
unix.SYS_ACCEPT4: []seccomp.Rule{
|
||||
{
|
||||
@@ -80,7 +80,11 @@ func hostInetFilters() seccomp.SyscallRules {
|
||||
// Generate rules for socket creation based on hostinet's supported
|
||||
// socket types.
|
||||
socketRules := []seccomp.Rule{}
|
||||
for _, sock := range hostinet.AllowedSocketTypes {
|
||||
stypes := hostinet.AllowedSocketTypes
|
||||
if allowRawSockets {
|
||||
stypes = append(stypes, hostinet.AllowedRawSocketTypes...)
|
||||
}
|
||||
for _, sock := range stypes {
|
||||
socketRules = append(socketRules, seccomp.Rule{
|
||||
seccomp.EqualTo(sock.Family),
|
||||
// We always set SOCK_NONBLOCK and SOCK_CLOEXEC
|
||||
|
||||
@@ -25,13 +25,14 @@ import (
|
||||
|
||||
// Options are seccomp filter related options.
|
||||
type Options struct {
|
||||
Platform platform.Platform
|
||||
HostNetwork bool
|
||||
HostFilesystem bool
|
||||
HostSocketCreate bool
|
||||
HostSocketOpen bool
|
||||
ProfileEnable bool
|
||||
ControllerFD int
|
||||
Platform platform.Platform
|
||||
HostNetwork bool
|
||||
HostNetworkRawSockets bool
|
||||
HostFilesystem bool
|
||||
HostSocketCreate bool
|
||||
HostSocketOpen bool
|
||||
ProfileEnable bool
|
||||
ControllerFD int
|
||||
}
|
||||
|
||||
// Install seccomp filters based on the given platform.
|
||||
@@ -44,8 +45,12 @@ func Install(opt Options) error {
|
||||
s.Merge(instrumentationFilters())
|
||||
|
||||
if opt.HostNetwork {
|
||||
Report("host networking enabled: syscall filters less restrictive!")
|
||||
s.Merge(hostInetFilters())
|
||||
if opt.HostNetworkRawSockets {
|
||||
Report("host networking (with raw sockets) enabled: syscall filters less restrictive!")
|
||||
} else {
|
||||
Report("host networking enabled: syscall filters less restrictive!")
|
||||
}
|
||||
s.Merge(hostInetFilters(opt.HostNetworkRawSockets))
|
||||
}
|
||||
if opt.ProfileEnable {
|
||||
Report("profile enabled: syscall filters less restrictive!")
|
||||
|
||||
+10
-8
@@ -569,14 +569,16 @@ func (l *Loader) installSeccompFilters() error {
|
||||
filter.Report("syscall filter is DISABLED. Running in less secure mode.")
|
||||
} else {
|
||||
hostUDS := l.root.conf.GetHostUDS()
|
||||
hostnet := l.root.conf.Network == config.NetworkHost
|
||||
opts := filter.Options{
|
||||
Platform: l.k.Platform,
|
||||
HostNetwork: l.root.conf.Network == config.NetworkHost,
|
||||
HostFilesystem: l.root.conf.DirectFS,
|
||||
HostSocketCreate: l.root.conf.DirectFS && hostUDS.AllowCreate(),
|
||||
HostSocketOpen: l.root.conf.DirectFS && hostUDS.AllowOpen(),
|
||||
ProfileEnable: l.root.conf.ProfileEnable,
|
||||
ControllerFD: l.ctrl.srv.FD(),
|
||||
Platform: l.k.Platform,
|
||||
HostNetwork: hostnet,
|
||||
HostNetworkRawSockets: hostnet && l.root.conf.EnableRaw,
|
||||
HostFilesystem: l.root.conf.DirectFS,
|
||||
HostSocketCreate: l.root.conf.DirectFS && hostUDS.AllowCreate(),
|
||||
HostSocketOpen: l.root.conf.DirectFS && hostUDS.AllowOpen(),
|
||||
ProfileEnable: l.root.conf.ProfileEnable,
|
||||
ControllerFD: l.ctrl.srv.FD(),
|
||||
}
|
||||
if err := filter.Install(opts); err != nil {
|
||||
return fmt.Errorf("installing seccomp filters: %w", err)
|
||||
@@ -606,7 +608,7 @@ func (l *Loader) run() error {
|
||||
// is configured after the loader is created and before Run() is called.
|
||||
log.Debugf("Configuring host network")
|
||||
s := l.k.RootNetworkNamespace().Stack().(*hostinet.Stack)
|
||||
if err := s.Configure(); err != nil {
|
||||
if err := s.Configure(l.root.conf.EnableRaw); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
+28
-9
@@ -32,6 +32,7 @@ import (
|
||||
"gvisor.dev/gvisor/pkg/abi/linux"
|
||||
"gvisor.dev/gvisor/pkg/bits"
|
||||
"gvisor.dev/gvisor/pkg/test/dockerutil"
|
||||
"gvisor.dev/gvisor/pkg/test/testutil"
|
||||
"gvisor.dev/gvisor/runsc/specutils"
|
||||
)
|
||||
|
||||
@@ -77,15 +78,24 @@ func TestExecPrivileged(t *testing.T) {
|
||||
d := dockerutil.MakeContainer(ctx, t)
|
||||
defer d.CleanUp(ctx)
|
||||
|
||||
// Start the container with all capabilities dropped.
|
||||
if err := d.Spawn(ctx, dockerutil.RunOpts{
|
||||
// Container will drop all capabilities.
|
||||
opts := dockerutil.RunOpts{
|
||||
Image: "basic/alpine",
|
||||
CapDrop: []string{"all"},
|
||||
}, "sh", "-c", "cat /proc/self/status; sleep 100"); err != nil {
|
||||
}
|
||||
|
||||
// But if we are running with host network stack and raw sockets, then
|
||||
// we require CAP_NET_RAW, so add that back.
|
||||
if testutil.IsRunningWithHostNet() && testutil.IsRunningWithNetRaw() {
|
||||
opts.CapAdd = []string{"NET_RAW"}
|
||||
}
|
||||
|
||||
// Start the container.
|
||||
if err := d.Spawn(ctx, opts, "sh", "-c", "cat /proc/self/status; sleep 100"); err != nil {
|
||||
t.Fatalf("docker run failed: %v", err)
|
||||
}
|
||||
|
||||
// Check that all capabilities where dropped from container.
|
||||
// Grab the capabilities from inside container.
|
||||
matches, err := d.WaitForOutputSubmatch(ctx, "CapEff:\t([0-9a-f]+)\n", 5*time.Second)
|
||||
if err != nil {
|
||||
t.Fatalf("WaitForOutputSubmatch() timeout: %v", err)
|
||||
@@ -98,12 +108,18 @@ func TestExecPrivileged(t *testing.T) {
|
||||
t.Fatalf("failed to convert capabilities %q: %v", matches[1], err)
|
||||
}
|
||||
t.Logf("Container capabilities: %#x", containerCaps)
|
||||
if containerCaps != 0 {
|
||||
t.Fatalf("Container should have no capabilities: %x", containerCaps)
|
||||
|
||||
// Expect no capabilities, unless raw sockets configured.
|
||||
var wantContainerCaps uint64
|
||||
if testutil.IsRunningWithNetRaw() {
|
||||
wantContainerCaps |= bits.MaskOf64(int(linux.CAP_NET_RAW))
|
||||
}
|
||||
if containerCaps != wantContainerCaps {
|
||||
t.Fatalf("Container caps got %x want %x", containerCaps, wantContainerCaps)
|
||||
}
|
||||
|
||||
// Check that 'exec --privileged' adds all capabilities, except for
|
||||
// CAP_NET_RAW.
|
||||
// Check that 'exec --privileged' adds all capabilities except
|
||||
// CAP_NET_RAW, unless raw sockets configured.
|
||||
got, err := d.Exec(ctx, dockerutil.ExecOpts{
|
||||
Privileged: true,
|
||||
}, "grep", "CapEff:", "/proc/self/status")
|
||||
@@ -111,7 +127,10 @@ func TestExecPrivileged(t *testing.T) {
|
||||
t.Fatalf("docker exec failed: %v", err)
|
||||
}
|
||||
t.Logf("Exec CapEff: %v", got)
|
||||
wantCaps := specutils.AllCapabilitiesUint64() &^ bits.MaskOf64(int(linux.CAP_NET_RAW))
|
||||
wantCaps := specutils.AllCapabilitiesUint64()
|
||||
if !testutil.IsRunningWithNetRaw() {
|
||||
wantCaps &= ^bits.MaskOf64(int(linux.CAP_NET_RAW))
|
||||
}
|
||||
wantStr := fmt.Sprintf("CapEff:\t%016x\n", wantCaps)
|
||||
if got == wantStr {
|
||||
// All good.
|
||||
|
||||
@@ -568,12 +568,6 @@ func TestLink(t *testing.T) {
|
||||
|
||||
// This test ensures we can run ping without errors.
|
||||
func TestPing4Loopback(t *testing.T) {
|
||||
if testutil.IsRunningWithHostNet() {
|
||||
// TODO(gvisor.dev/issue/5011): support ICMP sockets in hostnet and enable
|
||||
// this test.
|
||||
t.Skip("hostnet only supports TCP/UDP sockets, so ping is not supported.")
|
||||
}
|
||||
|
||||
runIntegrationTest(t, nil, "./ping4.sh")
|
||||
}
|
||||
|
||||
|
||||
@@ -447,6 +447,7 @@ syscall_test(
|
||||
|
||||
syscall_test(
|
||||
size = "medium",
|
||||
add_hostinet = True,
|
||||
# Takes too long under gotsan to run.
|
||||
tags = ["nogotsan"],
|
||||
test = "//test/syscalls/linux:ping_socket_test",
|
||||
@@ -557,14 +558,17 @@ syscall_test(
|
||||
)
|
||||
|
||||
syscall_test(
|
||||
add_hostinet = True,
|
||||
test = "//test/syscalls/linux:raw_socket_hdrincl_test",
|
||||
)
|
||||
|
||||
syscall_test(
|
||||
add_hostinet = True,
|
||||
test = "//test/syscalls/linux:raw_socket_icmp_test",
|
||||
)
|
||||
|
||||
syscall_test(
|
||||
add_hostinet = True,
|
||||
shard_count = more_shards,
|
||||
test = "//test/syscalls/linux:raw_socket_test",
|
||||
)
|
||||
|
||||
@@ -797,7 +797,7 @@ TEST_P(RawSocketTest, RecvBufLimits) {
|
||||
ASSERT_NO_FATAL_FAILURE(SendBuf(buf.data(), buf.size()));
|
||||
ASSERT_NO_FATAL_FAILURE(SendBuf(buf.data(), buf.size()));
|
||||
int sent = 4;
|
||||
if (IsRunningOnGvisor()) {
|
||||
if (IsRunningOnGvisor() && !IsRunningWithHostinet()) {
|
||||
// Linux seems to drop the 4th packet even though technically it should
|
||||
// fit in the receive buffer.
|
||||
ASSERT_NO_FATAL_FAILURE(SendBuf(buf.data(), buf.size()));
|
||||
@@ -1451,7 +1451,7 @@ TEST(RawSocketTest, SetIPv6ChecksumError_ReadShort) {
|
||||
ASSERT_NO_ERRNO_AND_VALUE(Socket(AF_INET6, SOCK_RAW, IPPROTO_UDP));
|
||||
|
||||
int intV = 2;
|
||||
if (IsRunningOnGvisor() && !IsRunningWithHostinet()) {
|
||||
if (IsRunningOnGvisor()) {
|
||||
// TODO(https://gvisor.dev/issue/6982): This is a deviation from Linux. We
|
||||
// should determine if we want to match the behaviour or handle the error
|
||||
// more gracefully.
|
||||
|
||||
@@ -244,7 +244,12 @@ TEST_F(RawSocketICMPTest, MultipleSocketReceive) {
|
||||
// A raw ICMP socket and ping socket should both receive the ICMP packets
|
||||
// intended for the ping socket.
|
||||
TEST_F(RawSocketICMPTest, RawAndPingSockets) {
|
||||
SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(HaveRawIPSocketCapability()));
|
||||
// By default, ping sockets cannot be created on Linux, even with root privs.
|
||||
// So we only run the test with gVisor and not hostinet, and even then require
|
||||
// CAP_NET_RAW.
|
||||
// See https://lwn.net/Articles/443051/
|
||||
SKIP_IF(!IsRunningOnGvisor() || IsRunningWithHostinet() ||
|
||||
ASSERT_NO_ERRNO_AND_VALUE(HaveRawIPSocketCapability()));
|
||||
|
||||
FileDescriptor ping_sock =
|
||||
ASSERT_NO_ERRNO_AND_VALUE(Socket(AF_INET, SOCK_DGRAM, IPPROTO_ICMP));
|
||||
@@ -294,7 +299,12 @@ TEST_F(RawSocketICMPTest, RawAndPingSockets) {
|
||||
// while a ping socket should not. Neither should be able to receieve a short
|
||||
// malformed packet.
|
||||
TEST_F(RawSocketICMPTest, ShortEchoRawAndPingSockets) {
|
||||
SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(HaveRawIPSocketCapability()));
|
||||
// By default, ping sockets cannot be created on Linux, even with root privs.
|
||||
// So we only run the test with gVisor and not hostinet, and even then require
|
||||
// CAP_NET_RAW.
|
||||
// See https://lwn.net/Articles/443051/
|
||||
SKIP_IF(!IsRunningOnGvisor() || IsRunningWithHostinet() ||
|
||||
ASSERT_NO_ERRNO_AND_VALUE(HaveRawIPSocketCapability()));
|
||||
|
||||
FileDescriptor ping_sock =
|
||||
ASSERT_NO_ERRNO_AND_VALUE(Socket(AF_INET, SOCK_DGRAM, IPPROTO_ICMP));
|
||||
@@ -335,7 +345,12 @@ TEST_F(RawSocketICMPTest, ShortEchoRawAndPingSockets) {
|
||||
// while ping socket should not.
|
||||
// Neither should be able to receieve a short malformed packet.
|
||||
TEST_F(RawSocketICMPTest, ShortEchoReplyRawAndPingSockets) {
|
||||
SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(HaveRawIPSocketCapability()));
|
||||
// By default, ping sockets cannot be created on Linux, even with root privs.
|
||||
// So we only run the test with gVisor and not hostinet, and even then require
|
||||
// CAP_NET_RAW.
|
||||
// See https://lwn.net/Articles/443051/
|
||||
SKIP_IF(!IsRunningOnGvisor() || IsRunningWithHostinet() ||
|
||||
ASSERT_NO_ERRNO_AND_VALUE(HaveRawIPSocketCapability()));
|
||||
|
||||
FileDescriptor ping_sock =
|
||||
ASSERT_NO_ERRNO_AND_VALUE(Socket(AF_INET, SOCK_DGRAM, IPPROTO_ICMP));
|
||||
|
||||
Reference in New Issue
Block a user