mirror of
https://github.com/netbirdio/gvisor.git
synced 2026-05-22 17:12:49 -07:00
add create-only raw sockets
These can be used by applications to manipulate iptables rules without enabling arbitrary reads from and writes to the underlying packet socket. PiperOrigin-RevId: 402924733
This commit is contained in:
committed by
gVisor bot
parent
8221893794
commit
1796cd89d5
@@ -0,0 +1,14 @@
|
||||
load("//tools:defs.bzl", "go_library")
|
||||
|
||||
package(licenses = ["notice"])
|
||||
|
||||
go_library(
|
||||
name = "noop",
|
||||
srcs = ["endpoint.go"],
|
||||
visibility = ["//pkg/tcpip/transport/raw:__pkg__"],
|
||||
deps = [
|
||||
"//pkg/tcpip",
|
||||
"//pkg/tcpip/stack",
|
||||
"//pkg/waiter",
|
||||
],
|
||||
)
|
||||
@@ -0,0 +1,172 @@
|
||||
// Copyright 2021 The gVisor Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Package noop contains an endpoint that implements all tcpip.Endpoint
|
||||
// functions as noops.
|
||||
package noop
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
|
||||
"gvisor.dev/gvisor/pkg/tcpip"
|
||||
"gvisor.dev/gvisor/pkg/tcpip/stack"
|
||||
"gvisor.dev/gvisor/pkg/waiter"
|
||||
)
|
||||
|
||||
// endpoint can be created, but all interactions have no effect or
|
||||
// return errors.
|
||||
//
|
||||
// +stateify savable
|
||||
type endpoint struct {
|
||||
tcpip.DefaultSocketOptionsHandler
|
||||
ops tcpip.SocketOptions
|
||||
}
|
||||
|
||||
// New returns an initialized noop endpoint.
|
||||
func New(stk *stack.Stack) tcpip.Endpoint {
|
||||
// ep.ops must be in a valid, initialized state for callers of
|
||||
// ep.SocketOptions.
|
||||
var ep endpoint
|
||||
ep.ops.InitHandler(&ep, stk, tcpip.GetStackSendBufferLimits, tcpip.GetStackReceiveBufferLimits)
|
||||
return &ep
|
||||
}
|
||||
|
||||
// Abort implements stack.TransportEndpoint.Abort.
|
||||
func (*endpoint) Abort() {
|
||||
// No-op.
|
||||
}
|
||||
|
||||
// Close implements tcpip.Endpoint.Close.
|
||||
func (*endpoint) Close() {
|
||||
// No-op.
|
||||
}
|
||||
|
||||
// ModerateRecvBuf implements tcpip.Endpoint.ModerateRecvBuf.
|
||||
func (*endpoint) ModerateRecvBuf(int) {
|
||||
// No-op.
|
||||
}
|
||||
|
||||
func (*endpoint) SetOwner(tcpip.PacketOwner) {
|
||||
// No-op.
|
||||
}
|
||||
|
||||
// Read implements tcpip.Endpoint.Read.
|
||||
func (*endpoint) Read(io.Writer, tcpip.ReadOptions) (tcpip.ReadResult, tcpip.Error) {
|
||||
return tcpip.ReadResult{}, &tcpip.ErrNotPermitted{}
|
||||
}
|
||||
|
||||
// Write implements tcpip.Endpoint.Write.
|
||||
func (*endpoint) Write(tcpip.Payloader, tcpip.WriteOptions) (int64, tcpip.Error) {
|
||||
return 0, &tcpip.ErrNotPermitted{}
|
||||
}
|
||||
|
||||
// Disconnect implements tcpip.Endpoint.Disconnect.
|
||||
func (*endpoint) Disconnect() tcpip.Error {
|
||||
return &tcpip.ErrNotSupported{}
|
||||
}
|
||||
|
||||
// Connect implements tcpip.Endpoint.Connect.
|
||||
func (*endpoint) Connect(tcpip.FullAddress) tcpip.Error {
|
||||
return &tcpip.ErrNotPermitted{}
|
||||
}
|
||||
|
||||
// Shutdown implements tcpip.Endpoint.Shutdown.
|
||||
func (*endpoint) Shutdown(tcpip.ShutdownFlags) tcpip.Error {
|
||||
return &tcpip.ErrNotPermitted{}
|
||||
}
|
||||
|
||||
// Listen implements tcpip.Endpoint.Listen.
|
||||
func (*endpoint) Listen(int) tcpip.Error {
|
||||
return &tcpip.ErrNotSupported{}
|
||||
}
|
||||
|
||||
// Accept implements tcpip.Endpoint.Accept.
|
||||
func (*endpoint) Accept(*tcpip.FullAddress) (tcpip.Endpoint, *waiter.Queue, tcpip.Error) {
|
||||
return nil, nil, &tcpip.ErrNotSupported{}
|
||||
}
|
||||
|
||||
// Bind implements tcpip.Endpoint.Bind.
|
||||
func (*endpoint) Bind(tcpip.FullAddress) tcpip.Error {
|
||||
return &tcpip.ErrNotPermitted{}
|
||||
}
|
||||
|
||||
// GetLocalAddress implements tcpip.Endpoint.GetLocalAddress.
|
||||
func (*endpoint) GetLocalAddress() (tcpip.FullAddress, tcpip.Error) {
|
||||
return tcpip.FullAddress{}, &tcpip.ErrNotSupported{}
|
||||
}
|
||||
|
||||
// GetRemoteAddress implements tcpip.Endpoint.GetRemoteAddress.
|
||||
func (*endpoint) GetRemoteAddress() (tcpip.FullAddress, tcpip.Error) {
|
||||
return tcpip.FullAddress{}, &tcpip.ErrNotConnected{}
|
||||
}
|
||||
|
||||
// Readiness implements tcpip.Endpoint.Readiness.
|
||||
func (*endpoint) Readiness(waiter.EventMask) waiter.EventMask {
|
||||
return 0
|
||||
}
|
||||
|
||||
// SetSockOpt implements tcpip.Endpoint.SetSockOpt.
|
||||
func (*endpoint) SetSockOpt(tcpip.SettableSocketOption) tcpip.Error {
|
||||
return &tcpip.ErrUnknownProtocolOption{}
|
||||
}
|
||||
|
||||
func (*endpoint) SetSockOptInt(tcpip.SockOptInt, int) tcpip.Error {
|
||||
return &tcpip.ErrUnknownProtocolOption{}
|
||||
}
|
||||
|
||||
// GetSockOpt implements tcpip.Endpoint.GetSockOpt.
|
||||
func (*endpoint) GetSockOpt(tcpip.GettableSocketOption) tcpip.Error {
|
||||
return &tcpip.ErrUnknownProtocolOption{}
|
||||
}
|
||||
|
||||
// GetSockOptInt implements tcpip.Endpoint.GetSockOptInt.
|
||||
func (*endpoint) GetSockOptInt(tcpip.SockOptInt) (int, tcpip.Error) {
|
||||
return 0, &tcpip.ErrUnknownProtocolOption{}
|
||||
}
|
||||
|
||||
// HandlePacket implements stack.RawTransportEndpoint.HandlePacket.
|
||||
func (*endpoint) HandlePacket(pkt *stack.PacketBuffer) {
|
||||
panic(fmt.Sprintf("unreachable: noop.endpoint should never be registered, but got packet: %+v", pkt))
|
||||
}
|
||||
|
||||
// State implements socket.Socket.State.
|
||||
func (*endpoint) State() uint32 {
|
||||
return 0
|
||||
}
|
||||
|
||||
// Wait implements stack.TransportEndpoint.Wait.
|
||||
func (*endpoint) Wait() {
|
||||
// No-op.
|
||||
}
|
||||
|
||||
// LastError implements tcpip.Endpoint.LastError.
|
||||
func (*endpoint) LastError() tcpip.Error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// SocketOptions implements tcpip.Endpoint.SocketOptions.
|
||||
func (ep *endpoint) SocketOptions() *tcpip.SocketOptions {
|
||||
return &ep.ops
|
||||
}
|
||||
|
||||
// Info implements tcpip.Endpoint.Info.
|
||||
func (*endpoint) Info() tcpip.EndpointInfo {
|
||||
return &stack.TransportEndpointInfo{}
|
||||
}
|
||||
|
||||
// Stats returns a pointer to the endpoint stats.
|
||||
func (*endpoint) Stats() tcpip.EndpointStats {
|
||||
return &tcpip.TransportEndpointStats{}
|
||||
}
|
||||
@@ -35,6 +35,7 @@ go_library(
|
||||
"//pkg/tcpip/stack",
|
||||
"//pkg/tcpip/transport",
|
||||
"//pkg/tcpip/transport/internal/network",
|
||||
"//pkg/tcpip/transport/internal/noop",
|
||||
"//pkg/tcpip/transport/packet",
|
||||
"//pkg/waiter",
|
||||
],
|
||||
|
||||
@@ -17,6 +17,7 @@ package raw
|
||||
import (
|
||||
"gvisor.dev/gvisor/pkg/tcpip"
|
||||
"gvisor.dev/gvisor/pkg/tcpip/stack"
|
||||
"gvisor.dev/gvisor/pkg/tcpip/transport/internal/noop"
|
||||
"gvisor.dev/gvisor/pkg/tcpip/transport/packet"
|
||||
"gvisor.dev/gvisor/pkg/waiter"
|
||||
)
|
||||
@@ -33,3 +34,18 @@ func (EndpointFactory) NewUnassociatedEndpoint(stack *stack.Stack, netProto tcpi
|
||||
func (EndpointFactory) NewPacketEndpoint(stack *stack.Stack, cooked bool, netProto tcpip.NetworkProtocolNumber, waiterQueue *waiter.Queue) (tcpip.Endpoint, tcpip.Error) {
|
||||
return packet.NewEndpoint(stack, cooked, netProto, waiterQueue)
|
||||
}
|
||||
|
||||
// CreateOnlyFactory implements stack.RawFactory. It allows creation of raw
|
||||
// endpoints that do not support reading, writing, binding, etc.
|
||||
type CreateOnlyFactory struct{}
|
||||
|
||||
// NewUnassociatedEndpoint implements stack.RawFactory.NewUnassociatedEndpoint.
|
||||
func (CreateOnlyFactory) NewUnassociatedEndpoint(stk *stack.Stack, _ tcpip.NetworkProtocolNumber, _ tcpip.TransportProtocolNumber, _ *waiter.Queue) (tcpip.Endpoint, tcpip.Error) {
|
||||
return noop.New(stk), nil
|
||||
}
|
||||
|
||||
// NewPacketEndpoint implements stack.RawFactory.NewPacketEndpoint.
|
||||
func (CreateOnlyFactory) NewPacketEndpoint(*stack.Stack, bool, tcpip.NetworkProtocolNumber, *waiter.Queue) (tcpip.Endpoint, tcpip.Error) {
|
||||
// This isn't needed by anything, so it isn't implemented.
|
||||
return nil, &tcpip.ErrNotPermitted{}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user