Remove uses of the binary package from networking code.
Co-Author: ayushranjan PiperOrigin-RevId: 370785009
This commit is contained in:
parent
9ec49aabd3
commit
f54d87b9ec
|
@ -245,6 +245,8 @@ const SizeOfXTCounters = 16
|
|||
// include/uapi/linux/netfilter/x_tables.h. That struct contains a union
|
||||
// exposing different data to the user and kernel, but this struct holds only
|
||||
// the user data.
|
||||
//
|
||||
// +marshal
|
||||
type XTEntryMatch struct {
|
||||
MatchSize uint16
|
||||
Name ExtensionName
|
||||
|
@ -284,6 +286,8 @@ const SizeOfXTGetRevision = 30
|
|||
// include/uapi/linux/netfilter/x_tables.h. That struct contains a union
|
||||
// exposing different data to the user and kernel, but this struct holds only
|
||||
// the user data.
|
||||
//
|
||||
// +marshal
|
||||
type XTEntryTarget struct {
|
||||
TargetSize uint16
|
||||
Name ExtensionName
|
||||
|
@ -306,6 +310,8 @@ type KernelXTEntryTarget struct {
|
|||
// XTStandardTarget is a built-in target, one of ACCEPT, DROP, JUMP, QUEUE,
|
||||
// RETURN, or jump. It corresponds to struct xt_standard_target in
|
||||
// include/uapi/linux/netfilter/x_tables.h.
|
||||
//
|
||||
// +marshal
|
||||
type XTStandardTarget struct {
|
||||
Target XTEntryTarget
|
||||
// A positive verdict indicates a jump, and is the offset from the
|
||||
|
@ -322,6 +328,8 @@ const SizeOfXTStandardTarget = 40
|
|||
// beginning of user-defined chains by putting the name of the chain in
|
||||
// ErrorName. It corresponds to struct xt_error_target in
|
||||
// include/uapi/linux/netfilter/x_tables.h.
|
||||
//
|
||||
// +marshal
|
||||
type XTErrorTarget struct {
|
||||
Target XTEntryTarget
|
||||
Name ErrorName
|
||||
|
@ -349,6 +357,8 @@ const (
|
|||
// NfNATIPV4Range corresponds to struct nf_nat_ipv4_range
|
||||
// in include/uapi/linux/netfilter/nf_nat.h. The fields are in
|
||||
// network byte order.
|
||||
//
|
||||
// +marshal
|
||||
type NfNATIPV4Range struct {
|
||||
Flags uint32
|
||||
MinIP [4]byte
|
||||
|
@ -359,6 +369,8 @@ type NfNATIPV4Range struct {
|
|||
|
||||
// NfNATIPV4MultiRangeCompat corresponds to struct
|
||||
// nf_nat_ipv4_multi_range_compat in include/uapi/linux/netfilter/nf_nat.h.
|
||||
//
|
||||
// +marshal
|
||||
type NfNATIPV4MultiRangeCompat struct {
|
||||
RangeSize uint32
|
||||
RangeIPV4 NfNATIPV4Range
|
||||
|
@ -366,6 +378,8 @@ type NfNATIPV4MultiRangeCompat struct {
|
|||
|
||||
// XTRedirectTarget triggers a redirect when reached.
|
||||
// Adding 4 bytes of padding to make the struct 8 byte aligned.
|
||||
//
|
||||
// +marshal
|
||||
type XTRedirectTarget struct {
|
||||
Target XTEntryTarget
|
||||
NfRange NfNATIPV4MultiRangeCompat
|
||||
|
@ -377,6 +391,8 @@ const SizeOfXTRedirectTarget = 56
|
|||
|
||||
// XTSNATTarget triggers Source NAT when reached.
|
||||
// Adding 4 bytes of padding to make the struct 8 byte aligned.
|
||||
//
|
||||
// +marshal
|
||||
type XTSNATTarget struct {
|
||||
Target XTEntryTarget
|
||||
NfRange NfNATIPV4MultiRangeCompat
|
||||
|
@ -463,6 +479,8 @@ var _ marshal.Marshallable = (*KernelIPTGetEntries)(nil)
|
|||
// IPTReplace is the argument for the IPT_SO_SET_REPLACE sockopt. It
|
||||
// corresponds to struct ipt_replace in
|
||||
// include/uapi/linux/netfilter_ipv4/ip_tables.h.
|
||||
//
|
||||
// +marshal
|
||||
type IPTReplace struct {
|
||||
Name TableName
|
||||
ValidHooks uint32
|
||||
|
@ -502,6 +520,8 @@ func (tn TableName) String() string {
|
|||
|
||||
// ErrorName holds the name of a netfilter error. These can also hold
|
||||
// user-defined chains.
|
||||
//
|
||||
// +marshal
|
||||
type ErrorName [XT_FUNCTION_MAXNAMELEN]byte
|
||||
|
||||
// String implements fmt.Stringer.
|
||||
|
@ -520,6 +540,8 @@ func goString(cstring []byte) string {
|
|||
|
||||
// XTTCP holds data for matching TCP packets. It corresponds to struct xt_tcp
|
||||
// in include/uapi/linux/netfilter/xt_tcpudp.h.
|
||||
//
|
||||
// +marshal
|
||||
type XTTCP struct {
|
||||
// SourcePortStart specifies the inclusive start of the range of source
|
||||
// ports to which the matcher applies.
|
||||
|
@ -573,6 +595,8 @@ const (
|
|||
|
||||
// XTUDP holds data for matching UDP packets. It corresponds to struct xt_udp
|
||||
// in include/uapi/linux/netfilter/xt_tcpudp.h.
|
||||
//
|
||||
// +marshal
|
||||
type XTUDP struct {
|
||||
// SourcePortStart is the inclusive start of the range of source ports
|
||||
// to which the matcher applies.
|
||||
|
@ -613,6 +637,8 @@ const (
|
|||
|
||||
// IPTOwnerInfo holds data for matching packets with owner. It corresponds
|
||||
// to struct ipt_owner_info in libxt_owner.c of iptables binary.
|
||||
//
|
||||
// +marshal
|
||||
type IPTOwnerInfo struct {
|
||||
// UID is user id which created the packet.
|
||||
UID uint32
|
||||
|
@ -634,7 +660,7 @@ type IPTOwnerInfo struct {
|
|||
Match uint8
|
||||
|
||||
// Invert flips the meaning of Match field.
|
||||
Invert uint8
|
||||
Invert uint8 `marshal:"unaligned"`
|
||||
}
|
||||
|
||||
// SizeOfIPTOwnerInfo is the size of an XTOwnerMatchInfo.
|
||||
|
|
|
@ -264,6 +264,8 @@ const (
|
|||
|
||||
// NFNATRange corresponds to struct nf_nat_range in
|
||||
// include/uapi/linux/netfilter/nf_nat.h.
|
||||
//
|
||||
// +marshal
|
||||
type NFNATRange struct {
|
||||
Flags uint32
|
||||
MinAddr Inet6Addr
|
||||
|
|
|
@ -53,6 +53,8 @@ type SockAddrNetlink struct {
|
|||
const SockAddrNetlinkSize = 12
|
||||
|
||||
// NetlinkMessageHeader is struct nlmsghdr, from uapi/linux/netlink.h.
|
||||
//
|
||||
// +marshal
|
||||
type NetlinkMessageHeader struct {
|
||||
Length uint32
|
||||
Type uint16
|
||||
|
@ -99,6 +101,8 @@ const NLMSG_ALIGNTO = 4
|
|||
// NetlinkAttrHeader is the header of a netlink attribute, followed by payload.
|
||||
//
|
||||
// This is struct nlattr, from uapi/linux/netlink.h.
|
||||
//
|
||||
// +marshal
|
||||
type NetlinkAttrHeader struct {
|
||||
Length uint16
|
||||
Type uint16
|
||||
|
@ -126,6 +130,8 @@ const (
|
|||
)
|
||||
|
||||
// NetlinkErrorMessage is struct nlmsgerr, from uapi/linux/netlink.h.
|
||||
//
|
||||
// +marshal
|
||||
type NetlinkErrorMessage struct {
|
||||
Error int32
|
||||
Header NetlinkMessageHeader
|
||||
|
|
|
@ -85,6 +85,8 @@ const (
|
|||
)
|
||||
|
||||
// InterfaceInfoMessage is struct ifinfomsg, from uapi/linux/rtnetlink.h.
|
||||
//
|
||||
// +marshal
|
||||
type InterfaceInfoMessage struct {
|
||||
Family uint8
|
||||
_ uint8
|
||||
|
@ -164,6 +166,8 @@ const (
|
|||
)
|
||||
|
||||
// InterfaceAddrMessage is struct ifaddrmsg, from uapi/linux/if_addr.h.
|
||||
//
|
||||
// +marshal
|
||||
type InterfaceAddrMessage struct {
|
||||
Family uint8
|
||||
PrefixLen uint8
|
||||
|
@ -193,6 +197,8 @@ const (
|
|||
)
|
||||
|
||||
// RouteMessage is struct rtmsg, from uapi/linux/rtnetlink.h.
|
||||
//
|
||||
// +marshal
|
||||
type RouteMessage struct {
|
||||
Family uint8
|
||||
DstLen uint8
|
||||
|
|
|
@ -15,7 +15,6 @@
|
|||
package linux
|
||||
|
||||
import (
|
||||
"gvisor.dev/gvisor/pkg/binary"
|
||||
"gvisor.dev/gvisor/pkg/marshal"
|
||||
)
|
||||
|
||||
|
@ -251,18 +250,24 @@ type SockAddrInet struct {
|
|||
}
|
||||
|
||||
// Inet6MulticastRequest is struct ipv6_mreq, from uapi/linux/in6.h.
|
||||
//
|
||||
// +marshal
|
||||
type Inet6MulticastRequest struct {
|
||||
MulticastAddr Inet6Addr
|
||||
InterfaceIndex int32
|
||||
}
|
||||
|
||||
// InetMulticastRequest is struct ip_mreq, from uapi/linux/in.h.
|
||||
//
|
||||
// +marshal
|
||||
type InetMulticastRequest struct {
|
||||
MulticastAddr InetAddr
|
||||
InterfaceAddr InetAddr
|
||||
}
|
||||
|
||||
// InetMulticastRequestWithNIC is struct ip_mreqn, from uapi/linux/in.h.
|
||||
//
|
||||
// +marshal
|
||||
type InetMulticastRequestWithNIC struct {
|
||||
InetMulticastRequest
|
||||
InterfaceIndex int32
|
||||
|
@ -491,7 +496,7 @@ type TCPInfo struct {
|
|||
}
|
||||
|
||||
// SizeOfTCPInfo is the binary size of a TCPInfo struct.
|
||||
var SizeOfTCPInfo = int(binary.Size(TCPInfo{}))
|
||||
var SizeOfTCPInfo = (*TCPInfo)(nil).SizeBytes()
|
||||
|
||||
// Control message types, from linux/socket.h.
|
||||
const (
|
||||
|
@ -502,6 +507,8 @@ const (
|
|||
// A ControlMessageHeader is the header for a socket control message.
|
||||
//
|
||||
// ControlMessageHeader represents struct cmsghdr from linux/socket.h.
|
||||
//
|
||||
// +marshal
|
||||
type ControlMessageHeader struct {
|
||||
Length uint64
|
||||
Level int32
|
||||
|
@ -510,7 +517,7 @@ type ControlMessageHeader struct {
|
|||
|
||||
// SizeOfControlMessageHeader is the binary size of a ControlMessageHeader
|
||||
// struct.
|
||||
var SizeOfControlMessageHeader = int(binary.Size(ControlMessageHeader{}))
|
||||
var SizeOfControlMessageHeader = (*ControlMessageHeader)(nil).SizeBytes()
|
||||
|
||||
// A ControlMessageCredentials is an SCM_CREDENTIALS socket control message.
|
||||
//
|
||||
|
@ -527,6 +534,7 @@ type ControlMessageCredentials struct {
|
|||
//
|
||||
// ControlMessageIPPacketInfo represents struct in_pktinfo from linux/in.h.
|
||||
//
|
||||
// +marshal
|
||||
// +stateify savable
|
||||
type ControlMessageIPPacketInfo struct {
|
||||
NIC int32
|
||||
|
@ -536,7 +544,7 @@ type ControlMessageIPPacketInfo struct {
|
|||
|
||||
// SizeOfControlMessageCredentials is the binary size of a
|
||||
// ControlMessageCredentials struct.
|
||||
var SizeOfControlMessageCredentials = int(binary.Size(ControlMessageCredentials{}))
|
||||
var SizeOfControlMessageCredentials = (*ControlMessageCredentials)(nil).SizeBytes()
|
||||
|
||||
// A ControlMessageRights is an SCM_RIGHTS socket control message.
|
||||
type ControlMessageRights []int32
|
||||
|
|
|
@ -14,3 +14,13 @@
|
|||
|
||||
// Package bits includes all bit related types and operations.
|
||||
package bits
|
||||
|
||||
// AlignUp rounds a length up to an alignment. align must be a power of 2.
|
||||
func AlignUp(length int, align uint) int {
|
||||
return (length + int(align) - 1) & ^(int(align) - 1)
|
||||
}
|
||||
|
||||
// AlignDown rounds a length down to an alignment. align must be a power of 2.
|
||||
func AlignDown(length int, align uint) int {
|
||||
return length & ^(int(align) - 1)
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@ go_library(
|
|||
srcs = [
|
||||
"marshal.go",
|
||||
"marshal_impl_util.go",
|
||||
"util.go",
|
||||
],
|
||||
visibility = [
|
||||
"//:sandbox",
|
||||
|
|
|
@ -125,6 +125,81 @@ func (b *ByteSlice) WriteTo(w io.Writer) (int64, error) {
|
|||
|
||||
var _ marshal.Marshallable = (*ByteSlice)(nil)
|
||||
|
||||
// The following set of functions are convenient shorthands for wrapping a
|
||||
// built-in type in a marshallable primitive type. For example:
|
||||
//
|
||||
// func useMarshallable(m marshal.Marshallable) { ... }
|
||||
//
|
||||
// // Compare:
|
||||
//
|
||||
// buf = []byte{...}
|
||||
// // useMarshallable(&primitive.ByteSlice(buf)) // Not allowed, can't address temp value.
|
||||
// bufP := primitive.ByteSlice(buf)
|
||||
// useMarshallable(&bufP)
|
||||
//
|
||||
// // Vs:
|
||||
//
|
||||
// useMarshallable(AsByteSlice(buf))
|
||||
//
|
||||
// Note that the argument to these function escapes, so avoid using them on very
|
||||
// hot code paths. But generally if a function accepts an interface as an
|
||||
// argument, the argument escapes anyways.
|
||||
|
||||
// AllocateInt8 returns x as a marshallable.
|
||||
func AllocateInt8(x int8) marshal.Marshallable {
|
||||
p := Int8(x)
|
||||
return &p
|
||||
}
|
||||
|
||||
// AllocateUint8 returns x as a marshallable.
|
||||
func AllocateUint8(x uint8) marshal.Marshallable {
|
||||
p := Uint8(x)
|
||||
return &p
|
||||
}
|
||||
|
||||
// AllocateInt16 returns x as a marshallable.
|
||||
func AllocateInt16(x int16) marshal.Marshallable {
|
||||
p := Int16(x)
|
||||
return &p
|
||||
}
|
||||
|
||||
// AllocateUint16 returns x as a marshallable.
|
||||
func AllocateUint16(x uint16) marshal.Marshallable {
|
||||
p := Uint16(x)
|
||||
return &p
|
||||
}
|
||||
|
||||
// AllocateInt32 returns x as a marshallable.
|
||||
func AllocateInt32(x int32) marshal.Marshallable {
|
||||
p := Int32(x)
|
||||
return &p
|
||||
}
|
||||
|
||||
// AllocateUint32 returns x as a marshallable.
|
||||
func AllocateUint32(x uint32) marshal.Marshallable {
|
||||
p := Uint32(x)
|
||||
return &p
|
||||
}
|
||||
|
||||
// AllocateInt64 returns x as a marshallable.
|
||||
func AllocateInt64(x int64) marshal.Marshallable {
|
||||
p := Int64(x)
|
||||
return &p
|
||||
}
|
||||
|
||||
// AllocateUint64 returns x as a marshallable.
|
||||
func AllocateUint64(x uint64) marshal.Marshallable {
|
||||
p := Uint64(x)
|
||||
return &p
|
||||
}
|
||||
|
||||
// AsByteSlice returns b as a marshallable. Note that this allocates a new slice
|
||||
// header, but does not copy the slice contents.
|
||||
func AsByteSlice(b []byte) marshal.Marshallable {
|
||||
bs := ByteSlice(b)
|
||||
return &bs
|
||||
}
|
||||
|
||||
// Below, we define some convenience functions for marshalling primitive types
|
||||
// using the newtypes above, without requiring superfluous casts.
|
||||
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
// Copyright 2020 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 marshal
|
||||
|
||||
// Marshal returns the serialized contents of m in a newly allocated
|
||||
// byte slice.
|
||||
func Marshal(m Marshallable) []byte {
|
||||
buf := make([]byte, m.SizeBytes())
|
||||
m.MarshalUnsafe(buf)
|
||||
return buf
|
||||
}
|
|
@ -8,7 +8,6 @@ go_library(
|
|||
visibility = ["//pkg/sentry:internal"],
|
||||
deps = [
|
||||
"//pkg/abi/linux",
|
||||
"//pkg/binary",
|
||||
"//pkg/context",
|
||||
"//pkg/hostarch",
|
||||
"//pkg/marshal",
|
||||
|
|
|
@ -14,9 +14,11 @@ go_library(
|
|||
visibility = ["//pkg/sentry:internal"],
|
||||
deps = [
|
||||
"//pkg/abi/linux",
|
||||
"//pkg/binary",
|
||||
"//pkg/bits",
|
||||
"//pkg/context",
|
||||
"//pkg/hostarch",
|
||||
"//pkg/marshal",
|
||||
"//pkg/marshal/primitive",
|
||||
"//pkg/sentry/fs",
|
||||
"//pkg/sentry/kernel",
|
||||
"//pkg/sentry/kernel/auth",
|
||||
|
|
|
@ -18,9 +18,11 @@ package control
|
|||
|
||||
import (
|
||||
"gvisor.dev/gvisor/pkg/abi/linux"
|
||||
"gvisor.dev/gvisor/pkg/binary"
|
||||
"gvisor.dev/gvisor/pkg/bits"
|
||||
"gvisor.dev/gvisor/pkg/context"
|
||||
"gvisor.dev/gvisor/pkg/hostarch"
|
||||
"gvisor.dev/gvisor/pkg/marshal"
|
||||
"gvisor.dev/gvisor/pkg/marshal/primitive"
|
||||
"gvisor.dev/gvisor/pkg/sentry/fs"
|
||||
"gvisor.dev/gvisor/pkg/sentry/kernel"
|
||||
"gvisor.dev/gvisor/pkg/sentry/kernel/auth"
|
||||
|
@ -193,7 +195,7 @@ func putUint32(buf []byte, n uint32) []byte {
|
|||
// putCmsg writes a control message header and as much data as will fit into
|
||||
// the unused capacity of a buffer.
|
||||
func putCmsg(buf []byte, flags int, msgType uint32, align uint, data []int32) ([]byte, int) {
|
||||
space := binary.AlignDown(cap(buf)-len(buf), 4)
|
||||
space := bits.AlignDown(cap(buf)-len(buf), 4)
|
||||
|
||||
// We can't write to space that doesn't exist, so if we are going to align
|
||||
// the available space, we must align down.
|
||||
|
@ -230,7 +232,7 @@ func putCmsg(buf []byte, flags int, msgType uint32, align uint, data []int32) ([
|
|||
return alignSlice(buf, align), flags
|
||||
}
|
||||
|
||||
func putCmsgStruct(buf []byte, msgLevel, msgType uint32, align uint, data interface{}) []byte {
|
||||
func putCmsgStruct(buf []byte, msgLevel, msgType uint32, align uint, data marshal.Marshallable) []byte {
|
||||
if cap(buf)-len(buf) < linux.SizeOfControlMessageHeader {
|
||||
return buf
|
||||
}
|
||||
|
@ -241,8 +243,7 @@ func putCmsgStruct(buf []byte, msgLevel, msgType uint32, align uint, data interf
|
|||
buf = putUint32(buf, msgType)
|
||||
|
||||
hdrBuf := buf
|
||||
|
||||
buf = binary.Marshal(buf, hostarch.ByteOrder, data)
|
||||
buf = append(buf, marshal.Marshal(data)...)
|
||||
|
||||
// If the control message data brought us over capacity, omit it.
|
||||
if cap(buf) != cap(ob) {
|
||||
|
@ -288,7 +289,7 @@ func PackCredentials(t *kernel.Task, creds SCMCredentials, buf []byte, flags int
|
|||
|
||||
// alignSlice extends a slice's length (up to the capacity) to align it.
|
||||
func alignSlice(buf []byte, align uint) []byte {
|
||||
aligned := binary.AlignUp(len(buf), align)
|
||||
aligned := bits.AlignUp(len(buf), align)
|
||||
if aligned > cap(buf) {
|
||||
// Linux allows unaligned data if there isn't room for alignment.
|
||||
// Since there isn't room for alignment, there isn't room for any
|
||||
|
@ -300,12 +301,13 @@ func alignSlice(buf []byte, align uint) []byte {
|
|||
|
||||
// PackTimestamp packs a SO_TIMESTAMP socket control message.
|
||||
func PackTimestamp(t *kernel.Task, timestamp int64, buf []byte) []byte {
|
||||
timestampP := linux.NsecToTimeval(timestamp)
|
||||
return putCmsgStruct(
|
||||
buf,
|
||||
linux.SOL_SOCKET,
|
||||
linux.SO_TIMESTAMP,
|
||||
t.Arch().Width(),
|
||||
linux.NsecToTimeval(timestamp),
|
||||
×tampP,
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -316,7 +318,7 @@ func PackInq(t *kernel.Task, inq int32, buf []byte) []byte {
|
|||
linux.SOL_TCP,
|
||||
linux.TCP_INQ,
|
||||
t.Arch().Width(),
|
||||
inq,
|
||||
primitive.AllocateInt32(inq),
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -327,7 +329,7 @@ func PackTOS(t *kernel.Task, tos uint8, buf []byte) []byte {
|
|||
linux.SOL_IP,
|
||||
linux.IP_TOS,
|
||||
t.Arch().Width(),
|
||||
tos,
|
||||
primitive.AllocateUint8(tos),
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -338,7 +340,7 @@ func PackTClass(t *kernel.Task, tClass uint32, buf []byte) []byte {
|
|||
linux.SOL_IPV6,
|
||||
linux.IPV6_TCLASS,
|
||||
t.Arch().Width(),
|
||||
tClass,
|
||||
primitive.AllocateUint32(tClass),
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -423,7 +425,7 @@ func PackControlMessages(t *kernel.Task, cmsgs socket.ControlMessages, buf []byt
|
|||
|
||||
// cmsgSpace is equivalent to CMSG_SPACE in Linux.
|
||||
func cmsgSpace(t *kernel.Task, dataLen int) int {
|
||||
return linux.SizeOfControlMessageHeader + binary.AlignUp(dataLen, t.Arch().Width())
|
||||
return linux.SizeOfControlMessageHeader + bits.AlignUp(dataLen, t.Arch().Width())
|
||||
}
|
||||
|
||||
// CmsgsSpace returns the number of bytes needed to fit the control messages
|
||||
|
@ -475,7 +477,7 @@ func Parse(t *kernel.Task, socketOrEndpoint interface{}, buf []byte, width uint)
|
|||
}
|
||||
|
||||
var h linux.ControlMessageHeader
|
||||
binary.Unmarshal(buf[i:i+linux.SizeOfControlMessageHeader], hostarch.ByteOrder, &h)
|
||||
h.UnmarshalUnsafe(buf[i : i+linux.SizeOfControlMessageHeader])
|
||||
|
||||
if h.Length < uint64(linux.SizeOfControlMessageHeader) {
|
||||
return socket.ControlMessages{}, syserror.EINVAL
|
||||
|
@ -491,7 +493,7 @@ func Parse(t *kernel.Task, socketOrEndpoint interface{}, buf []byte, width uint)
|
|||
case linux.SOL_SOCKET:
|
||||
switch h.Type {
|
||||
case linux.SCM_RIGHTS:
|
||||
rightsSize := binary.AlignDown(length, linux.SizeOfControlMessageRight)
|
||||
rightsSize := bits.AlignDown(length, linux.SizeOfControlMessageRight)
|
||||
numRights := rightsSize / linux.SizeOfControlMessageRight
|
||||
|
||||
if len(fds)+numRights > linux.SCM_MAX_FD {
|
||||
|
@ -502,7 +504,7 @@ func Parse(t *kernel.Task, socketOrEndpoint interface{}, buf []byte, width uint)
|
|||
fds = append(fds, int32(hostarch.ByteOrder.Uint32(buf[j:j+linux.SizeOfControlMessageRight])))
|
||||
}
|
||||
|
||||
i += binary.AlignUp(length, width)
|
||||
i += bits.AlignUp(length, width)
|
||||
|
||||
case linux.SCM_CREDENTIALS:
|
||||
if length < linux.SizeOfControlMessageCredentials {
|
||||
|
@ -510,23 +512,23 @@ func Parse(t *kernel.Task, socketOrEndpoint interface{}, buf []byte, width uint)
|
|||
}
|
||||
|
||||
var creds linux.ControlMessageCredentials
|
||||
binary.Unmarshal(buf[i:i+linux.SizeOfControlMessageCredentials], hostarch.ByteOrder, &creds)
|
||||
creds.UnmarshalUnsafe(buf[i : i+linux.SizeOfControlMessageCredentials])
|
||||
scmCreds, err := NewSCMCredentials(t, creds)
|
||||
if err != nil {
|
||||
return socket.ControlMessages{}, err
|
||||
}
|
||||
cmsgs.Unix.Credentials = scmCreds
|
||||
i += binary.AlignUp(length, width)
|
||||
i += bits.AlignUp(length, width)
|
||||
|
||||
case linux.SO_TIMESTAMP:
|
||||
if length < linux.SizeOfTimeval {
|
||||
return socket.ControlMessages{}, syserror.EINVAL
|
||||
}
|
||||
var ts linux.Timeval
|
||||
binary.Unmarshal(buf[i:i+linux.SizeOfTimeval], hostarch.ByteOrder, &ts)
|
||||
ts.UnmarshalUnsafe(buf[i : i+linux.SizeOfTimeval])
|
||||
cmsgs.IP.Timestamp = ts.ToNsecCapped()
|
||||
cmsgs.IP.HasTimestamp = true
|
||||
i += binary.AlignUp(length, width)
|
||||
i += bits.AlignUp(length, width)
|
||||
|
||||
default:
|
||||
// Unknown message type.
|
||||
|
@ -539,8 +541,10 @@ func Parse(t *kernel.Task, socketOrEndpoint interface{}, buf []byte, width uint)
|
|||
return socket.ControlMessages{}, syserror.EINVAL
|
||||
}
|
||||
cmsgs.IP.HasTOS = true
|
||||
binary.Unmarshal(buf[i:i+linux.SizeOfControlMessageTOS], hostarch.ByteOrder, &cmsgs.IP.TOS)
|
||||
i += binary.AlignUp(length, width)
|
||||
var tos primitive.Uint8
|
||||
tos.UnmarshalUnsafe(buf[i : i+linux.SizeOfControlMessageTOS])
|
||||
cmsgs.IP.TOS = uint8(tos)
|
||||
i += bits.AlignUp(length, width)
|
||||
|
||||
case linux.IP_PKTINFO:
|
||||
if length < linux.SizeOfControlMessageIPPacketInfo {
|
||||
|
@ -549,19 +553,19 @@ func Parse(t *kernel.Task, socketOrEndpoint interface{}, buf []byte, width uint)
|
|||
|
||||
cmsgs.IP.HasIPPacketInfo = true
|
||||
var packetInfo linux.ControlMessageIPPacketInfo
|
||||
binary.Unmarshal(buf[i:i+linux.SizeOfControlMessageIPPacketInfo], hostarch.ByteOrder, &packetInfo)
|
||||
packetInfo.UnmarshalUnsafe(buf[i : i+linux.SizeOfControlMessageIPPacketInfo])
|
||||
|
||||
cmsgs.IP.PacketInfo = packetInfo
|
||||
i += binary.AlignUp(length, width)
|
||||
i += bits.AlignUp(length, width)
|
||||
|
||||
case linux.IP_RECVORIGDSTADDR:
|
||||
var addr linux.SockAddrInet
|
||||
if length < addr.SizeBytes() {
|
||||
return socket.ControlMessages{}, syserror.EINVAL
|
||||
}
|
||||
binary.Unmarshal(buf[i:i+addr.SizeBytes()], hostarch.ByteOrder, &addr)
|
||||
addr.UnmarshalUnsafe(buf[i : i+addr.SizeBytes()])
|
||||
cmsgs.IP.OriginalDstAddress = &addr
|
||||
i += binary.AlignUp(length, width)
|
||||
i += bits.AlignUp(length, width)
|
||||
|
||||
case linux.IP_RECVERR:
|
||||
var errCmsg linux.SockErrCMsgIPv4
|
||||
|
@ -571,7 +575,7 @@ func Parse(t *kernel.Task, socketOrEndpoint interface{}, buf []byte, width uint)
|
|||
|
||||
errCmsg.UnmarshalBytes(buf[i : i+errCmsg.SizeBytes()])
|
||||
cmsgs.IP.SockErr = &errCmsg
|
||||
i += binary.AlignUp(length, width)
|
||||
i += bits.AlignUp(length, width)
|
||||
|
||||
default:
|
||||
return socket.ControlMessages{}, syserror.EINVAL
|
||||
|
@ -583,17 +587,19 @@ func Parse(t *kernel.Task, socketOrEndpoint interface{}, buf []byte, width uint)
|
|||
return socket.ControlMessages{}, syserror.EINVAL
|
||||
}
|
||||
cmsgs.IP.HasTClass = true
|
||||
binary.Unmarshal(buf[i:i+linux.SizeOfControlMessageTClass], hostarch.ByteOrder, &cmsgs.IP.TClass)
|
||||
i += binary.AlignUp(length, width)
|
||||
var tclass primitive.Uint32
|
||||
tclass.UnmarshalUnsafe(buf[i : i+linux.SizeOfControlMessageTClass])
|
||||
cmsgs.IP.TClass = uint32(tclass)
|
||||
i += bits.AlignUp(length, width)
|
||||
|
||||
case linux.IPV6_RECVORIGDSTADDR:
|
||||
var addr linux.SockAddrInet6
|
||||
if length < addr.SizeBytes() {
|
||||
return socket.ControlMessages{}, syserror.EINVAL
|
||||
}
|
||||
binary.Unmarshal(buf[i:i+addr.SizeBytes()], hostarch.ByteOrder, &addr)
|
||||
addr.UnmarshalUnsafe(buf[i : i+addr.SizeBytes()])
|
||||
cmsgs.IP.OriginalDstAddress = &addr
|
||||
i += binary.AlignUp(length, width)
|
||||
i += bits.AlignUp(length, width)
|
||||
|
||||
case linux.IPV6_RECVERR:
|
||||
var errCmsg linux.SockErrCMsgIPv6
|
||||
|
@ -603,7 +609,7 @@ func Parse(t *kernel.Task, socketOrEndpoint interface{}, buf []byte, width uint)
|
|||
|
||||
errCmsg.UnmarshalBytes(buf[i : i+errCmsg.SizeBytes()])
|
||||
cmsgs.IP.SockErr = &errCmsg
|
||||
i += binary.AlignUp(length, width)
|
||||
i += bits.AlignUp(length, width)
|
||||
|
||||
default:
|
||||
return socket.ControlMessages{}, syserror.EINVAL
|
||||
|
|
|
@ -17,7 +17,6 @@ go_library(
|
|||
visibility = ["//pkg/sentry:internal"],
|
||||
deps = [
|
||||
"//pkg/abi/linux",
|
||||
"//pkg/binary",
|
||||
"//pkg/context",
|
||||
"//pkg/fdnotifier",
|
||||
"//pkg/hostarch",
|
||||
|
|
|
@ -19,7 +19,6 @@ import (
|
|||
|
||||
"golang.org/x/sys/unix"
|
||||
"gvisor.dev/gvisor/pkg/abi/linux"
|
||||
"gvisor.dev/gvisor/pkg/binary"
|
||||
"gvisor.dev/gvisor/pkg/context"
|
||||
"gvisor.dev/gvisor/pkg/fdnotifier"
|
||||
"gvisor.dev/gvisor/pkg/hostarch"
|
||||
|
@ -529,7 +528,7 @@ func parseUnixControlMessages(unixControlMessages []unix.SocketControlMessage) s
|
|||
case linux.SO_TIMESTAMP:
|
||||
controlMessages.IP.HasTimestamp = true
|
||||
ts := linux.Timeval{}
|
||||
ts.UnmarshalBytes(unixCmsg.Data[:linux.SizeOfTimeval])
|
||||
ts.UnmarshalUnsafe(unixCmsg.Data[:linux.SizeOfTimeval])
|
||||
controlMessages.IP.Timestamp = ts.ToNsecCapped()
|
||||
}
|
||||
|
||||
|
@ -537,17 +536,19 @@ func parseUnixControlMessages(unixControlMessages []unix.SocketControlMessage) s
|
|||
switch unixCmsg.Header.Type {
|
||||
case linux.IP_TOS:
|
||||
controlMessages.IP.HasTOS = true
|
||||
binary.Unmarshal(unixCmsg.Data[:linux.SizeOfControlMessageTOS], hostarch.ByteOrder, &controlMessages.IP.TOS)
|
||||
var tos primitive.Uint8
|
||||
tos.UnmarshalUnsafe(unixCmsg.Data[:tos.SizeBytes()])
|
||||
controlMessages.IP.TOS = uint8(tos)
|
||||
|
||||
case linux.IP_PKTINFO:
|
||||
controlMessages.IP.HasIPPacketInfo = true
|
||||
var packetInfo linux.ControlMessageIPPacketInfo
|
||||
binary.Unmarshal(unixCmsg.Data[:linux.SizeOfControlMessageIPPacketInfo], hostarch.ByteOrder, &packetInfo)
|
||||
packetInfo.UnmarshalUnsafe(unixCmsg.Data[:packetInfo.SizeBytes()])
|
||||
controlMessages.IP.PacketInfo = packetInfo
|
||||
|
||||
case linux.IP_RECVORIGDSTADDR:
|
||||
var addr linux.SockAddrInet
|
||||
binary.Unmarshal(unixCmsg.Data[:addr.SizeBytes()], hostarch.ByteOrder, &addr)
|
||||
addr.UnmarshalUnsafe(unixCmsg.Data[:addr.SizeBytes()])
|
||||
controlMessages.IP.OriginalDstAddress = &addr
|
||||
|
||||
case unix.IP_RECVERR:
|
||||
|
@ -560,11 +561,13 @@ func parseUnixControlMessages(unixControlMessages []unix.SocketControlMessage) s
|
|||
switch unixCmsg.Header.Type {
|
||||
case linux.IPV6_TCLASS:
|
||||
controlMessages.IP.HasTClass = true
|
||||
binary.Unmarshal(unixCmsg.Data[:linux.SizeOfControlMessageTClass], hostarch.ByteOrder, &controlMessages.IP.TClass)
|
||||
var tclass primitive.Uint32
|
||||
tclass.UnmarshalUnsafe(unixCmsg.Data[:tclass.SizeBytes()])
|
||||
controlMessages.IP.TClass = uint32(tclass)
|
||||
|
||||
case linux.IPV6_RECVORIGDSTADDR:
|
||||
var addr linux.SockAddrInet6
|
||||
binary.Unmarshal(unixCmsg.Data[:addr.SizeBytes()], hostarch.ByteOrder, &addr)
|
||||
addr.UnmarshalUnsafe(unixCmsg.Data[:addr.SizeBytes()])
|
||||
controlMessages.IP.OriginalDstAddress = &addr
|
||||
|
||||
case unix.IPV6_RECVERR:
|
||||
|
@ -577,7 +580,9 @@ func parseUnixControlMessages(unixControlMessages []unix.SocketControlMessage) s
|
|||
switch unixCmsg.Header.Type {
|
||||
case linux.TCP_INQ:
|
||||
controlMessages.IP.HasInq = true
|
||||
binary.Unmarshal(unixCmsg.Data[:linux.SizeOfControlMessageInq], hostarch.ByteOrder, &controlMessages.IP.Inq)
|
||||
var inq primitive.Int32
|
||||
inq.UnmarshalUnsafe(unixCmsg.Data[:linux.SizeOfControlMessageInq])
|
||||
controlMessages.IP.Inq = int32(inq)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -691,7 +696,7 @@ func (s *socketOpsCommon) State() uint32 {
|
|||
return 0
|
||||
}
|
||||
|
||||
binary.Unmarshal(buf, hostarch.ByteOrder, &info)
|
||||
info.UnmarshalUnsafe(buf[:info.SizeBytes()])
|
||||
return uint32(info.State)
|
||||
}
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
package hostinet
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
|
@ -26,10 +27,10 @@ import (
|
|||
"syscall"
|
||||
|
||||
"golang.org/x/sys/unix"
|
||||
"gvisor.dev/gvisor/pkg/binary"
|
||||
"gvisor.dev/gvisor/pkg/abi/linux"
|
||||
"gvisor.dev/gvisor/pkg/context"
|
||||
"gvisor.dev/gvisor/pkg/hostarch"
|
||||
"gvisor.dev/gvisor/pkg/log"
|
||||
"gvisor.dev/gvisor/pkg/marshal/primitive"
|
||||
"gvisor.dev/gvisor/pkg/sentry/inet"
|
||||
"gvisor.dev/gvisor/pkg/syserr"
|
||||
"gvisor.dev/gvisor/pkg/syserror"
|
||||
|
@ -147,8 +148,8 @@ func ExtractHostInterfaces(links []syscall.NetlinkMessage, addrs []syscall.Netli
|
|||
if len(link.Data) < unix.SizeofIfInfomsg {
|
||||
return fmt.Errorf("RTM_GETLINK returned RTM_NEWLINK message with invalid data length (%d bytes, expected at least %d bytes)", len(link.Data), unix.SizeofIfInfomsg)
|
||||
}
|
||||
var ifinfo unix.IfInfomsg
|
||||
binary.Unmarshal(link.Data[:unix.SizeofIfInfomsg], hostarch.ByteOrder, &ifinfo)
|
||||
var ifinfo linux.InterfaceInfoMessage
|
||||
ifinfo.UnmarshalUnsafe(link.Data[:ifinfo.SizeBytes()])
|
||||
inetIF := inet.Interface{
|
||||
DeviceType: ifinfo.Type,
|
||||
Flags: ifinfo.Flags,
|
||||
|
@ -178,11 +179,11 @@ func ExtractHostInterfaces(links []syscall.NetlinkMessage, addrs []syscall.Netli
|
|||
if len(addr.Data) < unix.SizeofIfAddrmsg {
|
||||
return fmt.Errorf("RTM_GETADDR returned RTM_NEWADDR message with invalid data length (%d bytes, expected at least %d bytes)", len(addr.Data), unix.SizeofIfAddrmsg)
|
||||
}
|
||||
var ifaddr unix.IfAddrmsg
|
||||
binary.Unmarshal(addr.Data[:unix.SizeofIfAddrmsg], hostarch.ByteOrder, &ifaddr)
|
||||
var ifaddr linux.InterfaceAddrMessage
|
||||
ifaddr.UnmarshalUnsafe(addr.Data[:ifaddr.SizeBytes()])
|
||||
inetAddr := inet.InterfaceAddr{
|
||||
Family: ifaddr.Family,
|
||||
PrefixLen: ifaddr.Prefixlen,
|
||||
PrefixLen: ifaddr.PrefixLen,
|
||||
Flags: ifaddr.Flags,
|
||||
}
|
||||
attrs, err := syscall.ParseNetlinkRouteAttr(&addr)
|
||||
|
@ -210,13 +211,13 @@ func ExtractHostRoutes(routeMsgs []syscall.NetlinkMessage) ([]inet.Route, error)
|
|||
continue
|
||||
}
|
||||
|
||||
var ifRoute unix.RtMsg
|
||||
binary.Unmarshal(routeMsg.Data[:unix.SizeofRtMsg], hostarch.ByteOrder, &ifRoute)
|
||||
var ifRoute linux.RouteMessage
|
||||
ifRoute.UnmarshalUnsafe(routeMsg.Data[:ifRoute.SizeBytes()])
|
||||
inetRoute := inet.Route{
|
||||
Family: ifRoute.Family,
|
||||
DstLen: ifRoute.Dst_len,
|
||||
SrcLen: ifRoute.Src_len,
|
||||
TOS: ifRoute.Tos,
|
||||
DstLen: ifRoute.DstLen,
|
||||
SrcLen: ifRoute.SrcLen,
|
||||
TOS: ifRoute.TOS,
|
||||
Table: ifRoute.Table,
|
||||
Protocol: ifRoute.Protocol,
|
||||
Scope: ifRoute.Scope,
|
||||
|
@ -245,7 +246,9 @@ func ExtractHostRoutes(routeMsgs []syscall.NetlinkMessage) ([]inet.Route, error)
|
|||
if len(attr.Value) != expected {
|
||||
return nil, fmt.Errorf("RTM_GETROUTE returned RTM_NEWROUTE message with invalid attribute data length (%d bytes, expected %d bytes)", len(attr.Value), expected)
|
||||
}
|
||||
binary.Unmarshal(attr.Value, hostarch.ByteOrder, &inetRoute.OutputInterface)
|
||||
var outputIF primitive.Int32
|
||||
outputIF.UnmarshalUnsafe(attr.Value)
|
||||
inetRoute.OutputInterface = int32(outputIF)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -14,14 +14,16 @@ go_library(
|
|||
"tcp_matcher.go",
|
||||
"udp_matcher.go",
|
||||
],
|
||||
marshal = True,
|
||||
# This target depends on netstack and should only be used by epsocket,
|
||||
# which is allowed to depend on netstack.
|
||||
visibility = ["//pkg/sentry:internal"],
|
||||
deps = [
|
||||
"//pkg/abi/linux",
|
||||
"//pkg/binary",
|
||||
"//pkg/bits",
|
||||
"//pkg/hostarch",
|
||||
"//pkg/log",
|
||||
"//pkg/marshal",
|
||||
"//pkg/sentry/kernel",
|
||||
"//pkg/syserr",
|
||||
"//pkg/tcpip",
|
||||
|
|
|
@ -18,8 +18,7 @@ import (
|
|||
"fmt"
|
||||
|
||||
"gvisor.dev/gvisor/pkg/abi/linux"
|
||||
"gvisor.dev/gvisor/pkg/binary"
|
||||
"gvisor.dev/gvisor/pkg/hostarch"
|
||||
"gvisor.dev/gvisor/pkg/bits"
|
||||
"gvisor.dev/gvisor/pkg/syserr"
|
||||
"gvisor.dev/gvisor/pkg/tcpip"
|
||||
"gvisor.dev/gvisor/pkg/tcpip/stack"
|
||||
|
@ -79,7 +78,7 @@ func marshalEntryMatch(name string, data []byte) []byte {
|
|||
nflog("marshaling matcher %q", name)
|
||||
|
||||
// We have to pad this struct size to a multiple of 8 bytes.
|
||||
size := binary.AlignUp(linux.SizeOfXTEntryMatch+len(data), 8)
|
||||
size := bits.AlignUp(linux.SizeOfXTEntryMatch+len(data), 8)
|
||||
matcher := linux.KernelXTEntryMatch{
|
||||
XTEntryMatch: linux.XTEntryMatch{
|
||||
MatchSize: uint16(size),
|
||||
|
@ -88,9 +87,11 @@ func marshalEntryMatch(name string, data []byte) []byte {
|
|||
}
|
||||
copy(matcher.Name[:], name)
|
||||
|
||||
buf := make([]byte, 0, size)
|
||||
buf = binary.Marshal(buf, hostarch.ByteOrder, matcher)
|
||||
return append(buf, make([]byte, size-len(buf))...)
|
||||
buf := make([]byte, size)
|
||||
entryLen := matcher.XTEntryMatch.SizeBytes()
|
||||
matcher.XTEntryMatch.MarshalUnsafe(buf[:entryLen])
|
||||
copy(buf[entryLen:], matcher.Data)
|
||||
return buf
|
||||
}
|
||||
|
||||
func unmarshalMatcher(match linux.XTEntryMatch, filter stack.IPHeaderFilter, buf []byte) (stack.Matcher, error) {
|
||||
|
|
|
@ -18,8 +18,6 @@ import (
|
|||
"fmt"
|
||||
|
||||
"gvisor.dev/gvisor/pkg/abi/linux"
|
||||
"gvisor.dev/gvisor/pkg/binary"
|
||||
"gvisor.dev/gvisor/pkg/hostarch"
|
||||
"gvisor.dev/gvisor/pkg/syserr"
|
||||
"gvisor.dev/gvisor/pkg/tcpip"
|
||||
"gvisor.dev/gvisor/pkg/tcpip/header"
|
||||
|
@ -141,10 +139,9 @@ func modifyEntries4(stk *stack.Stack, optVal []byte, replace *linux.IPTReplace,
|
|||
return nil, syserr.ErrInvalidArgument
|
||||
}
|
||||
var entry linux.IPTEntry
|
||||
buf := optVal[:linux.SizeOfIPTEntry]
|
||||
binary.Unmarshal(buf, hostarch.ByteOrder, &entry)
|
||||
entry.UnmarshalUnsafe(optVal[:entry.SizeBytes()])
|
||||
initialOptValLen := len(optVal)
|
||||
optVal = optVal[linux.SizeOfIPTEntry:]
|
||||
optVal = optVal[entry.SizeBytes():]
|
||||
|
||||
if entry.TargetOffset < linux.SizeOfIPTEntry {
|
||||
nflog("entry has too-small target offset %d", entry.TargetOffset)
|
||||
|
|
|
@ -18,8 +18,6 @@ import (
|
|||
"fmt"
|
||||
|
||||
"gvisor.dev/gvisor/pkg/abi/linux"
|
||||
"gvisor.dev/gvisor/pkg/binary"
|
||||
"gvisor.dev/gvisor/pkg/hostarch"
|
||||
"gvisor.dev/gvisor/pkg/syserr"
|
||||
"gvisor.dev/gvisor/pkg/tcpip"
|
||||
"gvisor.dev/gvisor/pkg/tcpip/header"
|
||||
|
@ -144,10 +142,9 @@ func modifyEntries6(stk *stack.Stack, optVal []byte, replace *linux.IPTReplace,
|
|||
return nil, syserr.ErrInvalidArgument
|
||||
}
|
||||
var entry linux.IP6TEntry
|
||||
buf := optVal[:linux.SizeOfIP6TEntry]
|
||||
binary.Unmarshal(buf, hostarch.ByteOrder, &entry)
|
||||
entry.UnmarshalUnsafe(optVal[:entry.SizeBytes()])
|
||||
initialOptValLen := len(optVal)
|
||||
optVal = optVal[linux.SizeOfIP6TEntry:]
|
||||
optVal = optVal[entry.SizeBytes():]
|
||||
|
||||
if entry.TargetOffset < linux.SizeOfIP6TEntry {
|
||||
nflog("entry has too-small target offset %d", entry.TargetOffset)
|
||||
|
|
|
@ -22,7 +22,6 @@ import (
|
|||
"fmt"
|
||||
|
||||
"gvisor.dev/gvisor/pkg/abi/linux"
|
||||
"gvisor.dev/gvisor/pkg/binary"
|
||||
"gvisor.dev/gvisor/pkg/hostarch"
|
||||
"gvisor.dev/gvisor/pkg/log"
|
||||
"gvisor.dev/gvisor/pkg/sentry/kernel"
|
||||
|
@ -121,7 +120,7 @@ func GetEntries4(t *kernel.Task, stack *stack.Stack, outPtr hostarch.Addr, outLe
|
|||
nflog("couldn't read entries: %v", err)
|
||||
return linux.KernelIPTGetEntries{}, syserr.ErrInvalidArgument
|
||||
}
|
||||
if binary.Size(entries) > uintptr(outLen) {
|
||||
if entries.SizeBytes() > outLen {
|
||||
nflog("insufficient GetEntries output size: %d", uintptr(outLen))
|
||||
return linux.KernelIPTGetEntries{}, syserr.ErrInvalidArgument
|
||||
}
|
||||
|
@ -146,7 +145,7 @@ func GetEntries6(t *kernel.Task, stack *stack.Stack, outPtr hostarch.Addr, outLe
|
|||
nflog("couldn't read entries: %v", err)
|
||||
return linux.KernelIP6TGetEntries{}, syserr.ErrInvalidArgument
|
||||
}
|
||||
if binary.Size(entries) > uintptr(outLen) {
|
||||
if entries.SizeBytes() > outLen {
|
||||
nflog("insufficient GetEntries output size: %d", uintptr(outLen))
|
||||
return linux.KernelIP6TGetEntries{}, syserr.ErrInvalidArgument
|
||||
}
|
||||
|
@ -179,7 +178,7 @@ func SetEntries(stk *stack.Stack, optVal []byte, ipv6 bool) *syserr.Error {
|
|||
var replace linux.IPTReplace
|
||||
replaceBuf := optVal[:linux.SizeOfIPTReplace]
|
||||
optVal = optVal[linux.SizeOfIPTReplace:]
|
||||
binary.Unmarshal(replaceBuf, hostarch.ByteOrder, &replace)
|
||||
replace.UnmarshalBytes(replaceBuf)
|
||||
|
||||
// TODO(gvisor.dev/issue/170): Support other tables.
|
||||
var table stack.Table
|
||||
|
@ -309,8 +308,8 @@ func parseMatchers(filter stack.IPHeaderFilter, optVal []byte) ([]stack.Matcher,
|
|||
return nil, fmt.Errorf("optVal has insufficient size for entry match: %d", len(optVal))
|
||||
}
|
||||
var match linux.XTEntryMatch
|
||||
buf := optVal[:linux.SizeOfXTEntryMatch]
|
||||
binary.Unmarshal(buf, hostarch.ByteOrder, &match)
|
||||
buf := optVal[:match.SizeBytes()]
|
||||
match.UnmarshalUnsafe(buf)
|
||||
nflog("set entries: parsed entry match %q: %+v", match.Name.String(), match)
|
||||
|
||||
// Check some invariants.
|
||||
|
|
|
@ -18,8 +18,7 @@ import (
|
|||
"fmt"
|
||||
|
||||
"gvisor.dev/gvisor/pkg/abi/linux"
|
||||
"gvisor.dev/gvisor/pkg/binary"
|
||||
"gvisor.dev/gvisor/pkg/hostarch"
|
||||
"gvisor.dev/gvisor/pkg/marshal"
|
||||
"gvisor.dev/gvisor/pkg/tcpip/stack"
|
||||
)
|
||||
|
||||
|
@ -59,8 +58,8 @@ func (ownerMarshaler) marshal(mr matcher) []byte {
|
|||
}
|
||||
}
|
||||
|
||||
buf := make([]byte, 0, linux.SizeOfIPTOwnerInfo)
|
||||
return marshalEntryMatch(matcherNameOwner, binary.Marshal(buf, hostarch.ByteOrder, iptOwnerInfo))
|
||||
buf := marshal.Marshal(&iptOwnerInfo)
|
||||
return marshalEntryMatch(matcherNameOwner, buf)
|
||||
}
|
||||
|
||||
// unmarshal implements matchMaker.unmarshal.
|
||||
|
@ -72,7 +71,7 @@ func (ownerMarshaler) unmarshal(buf []byte, filter stack.IPHeaderFilter) (stack.
|
|||
// For alignment reasons, the match's total size may
|
||||
// exceed what's strictly necessary to hold matchData.
|
||||
var matchData linux.IPTOwnerInfo
|
||||
binary.Unmarshal(buf[:linux.SizeOfIPTOwnerInfo], hostarch.ByteOrder, &matchData)
|
||||
matchData.UnmarshalUnsafe(buf[:linux.SizeOfIPTOwnerInfo])
|
||||
nflog("parseMatchers: parsed IPTOwnerInfo: %+v", matchData)
|
||||
|
||||
var owner OwnerMatcher
|
||||
|
|
|
@ -15,11 +15,12 @@
|
|||
package netfilter
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
|
||||
"gvisor.dev/gvisor/pkg/abi/linux"
|
||||
"gvisor.dev/gvisor/pkg/binary"
|
||||
"gvisor.dev/gvisor/pkg/hostarch"
|
||||
"gvisor.dev/gvisor/pkg/marshal"
|
||||
"gvisor.dev/gvisor/pkg/syserr"
|
||||
"gvisor.dev/gvisor/pkg/tcpip"
|
||||
"gvisor.dev/gvisor/pkg/tcpip/header"
|
||||
|
@ -189,8 +190,7 @@ func (*standardTargetMaker) marshal(target target) []byte {
|
|||
Verdict: verdict,
|
||||
}
|
||||
|
||||
ret := make([]byte, 0, linux.SizeOfXTStandardTarget)
|
||||
return binary.Marshal(ret, hostarch.ByteOrder, xt)
|
||||
return marshal.Marshal(&xt)
|
||||
}
|
||||
|
||||
func (*standardTargetMaker) unmarshal(buf []byte, filter stack.IPHeaderFilter) (target, *syserr.Error) {
|
||||
|
@ -199,8 +199,7 @@ func (*standardTargetMaker) unmarshal(buf []byte, filter stack.IPHeaderFilter) (
|
|||
return nil, syserr.ErrInvalidArgument
|
||||
}
|
||||
var standardTarget linux.XTStandardTarget
|
||||
buf = buf[:linux.SizeOfXTStandardTarget]
|
||||
binary.Unmarshal(buf, hostarch.ByteOrder, &standardTarget)
|
||||
standardTarget.UnmarshalUnsafe(buf[:standardTarget.SizeBytes()])
|
||||
|
||||
if standardTarget.Verdict < 0 {
|
||||
// A Verdict < 0 indicates a non-jump verdict.
|
||||
|
@ -245,8 +244,7 @@ func (*errorTargetMaker) marshal(target target) []byte {
|
|||
copy(xt.Name[:], errorName)
|
||||
copy(xt.Target.Name[:], ErrorTargetName)
|
||||
|
||||
ret := make([]byte, 0, linux.SizeOfXTErrorTarget)
|
||||
return binary.Marshal(ret, hostarch.ByteOrder, xt)
|
||||
return marshal.Marshal(&xt)
|
||||
}
|
||||
|
||||
func (*errorTargetMaker) unmarshal(buf []byte, filter stack.IPHeaderFilter) (target, *syserr.Error) {
|
||||
|
@ -256,7 +254,7 @@ func (*errorTargetMaker) unmarshal(buf []byte, filter stack.IPHeaderFilter) (tar
|
|||
}
|
||||
var errTgt linux.XTErrorTarget
|
||||
buf = buf[:linux.SizeOfXTErrorTarget]
|
||||
binary.Unmarshal(buf, hostarch.ByteOrder, &errTgt)
|
||||
errTgt.UnmarshalUnsafe(buf)
|
||||
|
||||
// Error targets are used in 2 cases:
|
||||
// * An actual error case. These rules have an error named
|
||||
|
@ -299,12 +297,11 @@ func (*redirectTargetMaker) marshal(target target) []byte {
|
|||
}
|
||||
copy(xt.Target.Name[:], RedirectTargetName)
|
||||
|
||||
ret := make([]byte, 0, linux.SizeOfXTRedirectTarget)
|
||||
xt.NfRange.RangeSize = 1
|
||||
xt.NfRange.RangeIPV4.Flags |= linux.NF_NAT_RANGE_PROTO_SPECIFIED
|
||||
xt.NfRange.RangeIPV4.MinPort = htons(rt.Port)
|
||||
xt.NfRange.RangeIPV4.MaxPort = xt.NfRange.RangeIPV4.MinPort
|
||||
return binary.Marshal(ret, hostarch.ByteOrder, xt)
|
||||
return marshal.Marshal(&xt)
|
||||
}
|
||||
|
||||
func (*redirectTargetMaker) unmarshal(buf []byte, filter stack.IPHeaderFilter) (target, *syserr.Error) {
|
||||
|
@ -320,7 +317,7 @@ func (*redirectTargetMaker) unmarshal(buf []byte, filter stack.IPHeaderFilter) (
|
|||
|
||||
var rt linux.XTRedirectTarget
|
||||
buf = buf[:linux.SizeOfXTRedirectTarget]
|
||||
binary.Unmarshal(buf, hostarch.ByteOrder, &rt)
|
||||
rt.UnmarshalUnsafe(buf)
|
||||
|
||||
// Copy linux.XTRedirectTarget to stack.RedirectTarget.
|
||||
target := redirectTarget{RedirectTarget: stack.RedirectTarget{
|
||||
|
@ -359,6 +356,7 @@ func (*redirectTargetMaker) unmarshal(buf []byte, filter stack.IPHeaderFilter) (
|
|||
return &target, nil
|
||||
}
|
||||
|
||||
// +marshal
|
||||
type nfNATTarget struct {
|
||||
Target linux.XTEntryTarget
|
||||
Range linux.NFNATRange
|
||||
|
@ -394,8 +392,7 @@ func (*nfNATTargetMaker) marshal(target target) []byte {
|
|||
nt.Range.MinProto = htons(rt.Port)
|
||||
nt.Range.MaxProto = nt.Range.MinProto
|
||||
|
||||
ret := make([]byte, 0, nfNATMarshalledSize)
|
||||
return binary.Marshal(ret, hostarch.ByteOrder, nt)
|
||||
return marshal.Marshal(&nt)
|
||||
}
|
||||
|
||||
func (*nfNATTargetMaker) unmarshal(buf []byte, filter stack.IPHeaderFilter) (target, *syserr.Error) {
|
||||
|
@ -411,7 +408,7 @@ func (*nfNATTargetMaker) unmarshal(buf []byte, filter stack.IPHeaderFilter) (tar
|
|||
|
||||
var natRange linux.NFNATRange
|
||||
buf = buf[linux.SizeOfXTEntryTarget:nfNATMarshalledSize]
|
||||
binary.Unmarshal(buf, hostarch.ByteOrder, &natRange)
|
||||
natRange.UnmarshalUnsafe(buf)
|
||||
|
||||
// We don't support port or address ranges.
|
||||
if natRange.MinAddr != natRange.MaxAddr {
|
||||
|
@ -468,8 +465,7 @@ func (*snatTargetMakerV4) marshal(target target) []byte {
|
|||
xt.NfRange.RangeIPV4.MaxPort = xt.NfRange.RangeIPV4.MinPort
|
||||
copy(xt.NfRange.RangeIPV4.MinIP[:], st.Addr)
|
||||
copy(xt.NfRange.RangeIPV4.MaxIP[:], st.Addr)
|
||||
ret := make([]byte, 0, linux.SizeOfXTSNATTarget)
|
||||
return binary.Marshal(ret, hostarch.ByteOrder, xt)
|
||||
return marshal.Marshal(&xt)
|
||||
}
|
||||
|
||||
func (*snatTargetMakerV4) unmarshal(buf []byte, filter stack.IPHeaderFilter) (target, *syserr.Error) {
|
||||
|
@ -485,7 +481,7 @@ func (*snatTargetMakerV4) unmarshal(buf []byte, filter stack.IPHeaderFilter) (ta
|
|||
|
||||
var st linux.XTSNATTarget
|
||||
buf = buf[:linux.SizeOfXTSNATTarget]
|
||||
binary.Unmarshal(buf, hostarch.ByteOrder, &st)
|
||||
st.UnmarshalUnsafe(buf)
|
||||
|
||||
// Copy linux.XTSNATTarget to stack.SNATTarget.
|
||||
target := snatTarget{SNATTarget: stack.SNATTarget{
|
||||
|
@ -550,8 +546,7 @@ func (*snatTargetMakerV6) marshal(target target) []byte {
|
|||
nt.Range.MinProto = htons(st.Port)
|
||||
nt.Range.MaxProto = nt.Range.MinProto
|
||||
|
||||
ret := make([]byte, 0, nfNATMarshalledSize)
|
||||
return binary.Marshal(ret, hostarch.ByteOrder, nt)
|
||||
return marshal.Marshal(&nt)
|
||||
}
|
||||
|
||||
func (*snatTargetMakerV6) unmarshal(buf []byte, filter stack.IPHeaderFilter) (target, *syserr.Error) {
|
||||
|
@ -567,7 +562,7 @@ func (*snatTargetMakerV6) unmarshal(buf []byte, filter stack.IPHeaderFilter) (ta
|
|||
|
||||
var natRange linux.NFNATRange
|
||||
buf = buf[linux.SizeOfXTEntryTarget:nfNATMarshalledSize]
|
||||
binary.Unmarshal(buf, hostarch.ByteOrder, &natRange)
|
||||
natRange.UnmarshalUnsafe(buf)
|
||||
|
||||
// TODO(gvisor.dev/issue/5689): Support port or address ranges.
|
||||
if natRange.MinAddr != natRange.MaxAddr {
|
||||
|
@ -631,8 +626,7 @@ func parseTarget(filter stack.IPHeaderFilter, optVal []byte, ipv6 bool) (stack.T
|
|||
return nil, syserr.ErrInvalidArgument
|
||||
}
|
||||
var target linux.XTEntryTarget
|
||||
buf := optVal[:linux.SizeOfXTEntryTarget]
|
||||
binary.Unmarshal(buf, hostarch.ByteOrder, &target)
|
||||
target.UnmarshalUnsafe(optVal[:target.SizeBytes()])
|
||||
|
||||
return unmarshalTarget(target, filter, optVal)
|
||||
}
|
||||
|
|
|
@ -18,8 +18,7 @@ import (
|
|||
"fmt"
|
||||
|
||||
"gvisor.dev/gvisor/pkg/abi/linux"
|
||||
"gvisor.dev/gvisor/pkg/binary"
|
||||
"gvisor.dev/gvisor/pkg/hostarch"
|
||||
"gvisor.dev/gvisor/pkg/marshal"
|
||||
"gvisor.dev/gvisor/pkg/tcpip/header"
|
||||
"gvisor.dev/gvisor/pkg/tcpip/stack"
|
||||
)
|
||||
|
@ -47,8 +46,7 @@ func (tcpMarshaler) marshal(mr matcher) []byte {
|
|||
DestinationPortStart: matcher.destinationPortStart,
|
||||
DestinationPortEnd: matcher.destinationPortEnd,
|
||||
}
|
||||
buf := make([]byte, 0, linux.SizeOfXTTCP)
|
||||
return marshalEntryMatch(matcherNameTCP, binary.Marshal(buf, hostarch.ByteOrder, xttcp))
|
||||
return marshalEntryMatch(matcherNameTCP, marshal.Marshal(&xttcp))
|
||||
}
|
||||
|
||||
// unmarshal implements matchMaker.unmarshal.
|
||||
|
@ -60,7 +58,7 @@ func (tcpMarshaler) unmarshal(buf []byte, filter stack.IPHeaderFilter) (stack.Ma
|
|||
// For alignment reasons, the match's total size may
|
||||
// exceed what's strictly necessary to hold matchData.
|
||||
var matchData linux.XTTCP
|
||||
binary.Unmarshal(buf[:linux.SizeOfXTTCP], hostarch.ByteOrder, &matchData)
|
||||
matchData.UnmarshalUnsafe(buf[:matchData.SizeBytes()])
|
||||
nflog("parseMatchers: parsed XTTCP: %+v", matchData)
|
||||
|
||||
if matchData.Option != 0 ||
|
||||
|
|
|
@ -18,8 +18,7 @@ import (
|
|||
"fmt"
|
||||
|
||||
"gvisor.dev/gvisor/pkg/abi/linux"
|
||||
"gvisor.dev/gvisor/pkg/binary"
|
||||
"gvisor.dev/gvisor/pkg/hostarch"
|
||||
"gvisor.dev/gvisor/pkg/marshal"
|
||||
"gvisor.dev/gvisor/pkg/tcpip/header"
|
||||
"gvisor.dev/gvisor/pkg/tcpip/stack"
|
||||
)
|
||||
|
@ -47,8 +46,7 @@ func (udpMarshaler) marshal(mr matcher) []byte {
|
|||
DestinationPortStart: matcher.destinationPortStart,
|
||||
DestinationPortEnd: matcher.destinationPortEnd,
|
||||
}
|
||||
buf := make([]byte, 0, linux.SizeOfXTUDP)
|
||||
return marshalEntryMatch(matcherNameUDP, binary.Marshal(buf, hostarch.ByteOrder, xtudp))
|
||||
return marshalEntryMatch(matcherNameUDP, marshal.Marshal(&xtudp))
|
||||
}
|
||||
|
||||
// unmarshal implements matchMaker.unmarshal.
|
||||
|
@ -60,7 +58,7 @@ func (udpMarshaler) unmarshal(buf []byte, filter stack.IPHeaderFilter) (stack.Ma
|
|||
// For alignment reasons, the match's total size may exceed what's
|
||||
// strictly necessary to hold matchData.
|
||||
var matchData linux.XTUDP
|
||||
binary.Unmarshal(buf[:linux.SizeOfXTUDP], hostarch.ByteOrder, &matchData)
|
||||
matchData.UnmarshalUnsafe(buf[:matchData.SizeBytes()])
|
||||
nflog("parseMatchers: parsed XTUDP: %+v", matchData)
|
||||
|
||||
if matchData.InverseFlags != 0 {
|
||||
|
|
|
@ -14,7 +14,7 @@ go_library(
|
|||
visibility = ["//pkg/sentry:internal"],
|
||||
deps = [
|
||||
"//pkg/abi/linux",
|
||||
"//pkg/binary",
|
||||
"//pkg/bits",
|
||||
"//pkg/context",
|
||||
"//pkg/hostarch",
|
||||
"//pkg/marshal",
|
||||
|
@ -50,5 +50,7 @@ go_test(
|
|||
deps = [
|
||||
":netlink",
|
||||
"//pkg/abi/linux",
|
||||
"//pkg/marshal",
|
||||
"//pkg/marshal/primitive",
|
||||
],
|
||||
)
|
||||
|
|
|
@ -19,15 +19,17 @@ import (
|
|||
"math"
|
||||
|
||||
"gvisor.dev/gvisor/pkg/abi/linux"
|
||||
"gvisor.dev/gvisor/pkg/binary"
|
||||
"gvisor.dev/gvisor/pkg/bits"
|
||||
"gvisor.dev/gvisor/pkg/hostarch"
|
||||
"gvisor.dev/gvisor/pkg/marshal"
|
||||
"gvisor.dev/gvisor/pkg/marshal/primitive"
|
||||
)
|
||||
|
||||
// alignPad returns the length of padding required for alignment.
|
||||
//
|
||||
// Preconditions: align is a power of two.
|
||||
func alignPad(length int, align uint) int {
|
||||
return binary.AlignUp(length, align) - length
|
||||
return bits.AlignUp(length, align) - length
|
||||
}
|
||||
|
||||
// Message contains a complete serialized netlink message.
|
||||
|
@ -42,7 +44,7 @@ type Message struct {
|
|||
func NewMessage(hdr linux.NetlinkMessageHeader) *Message {
|
||||
return &Message{
|
||||
hdr: hdr,
|
||||
buf: binary.Marshal(nil, hostarch.ByteOrder, hdr),
|
||||
buf: marshal.Marshal(&hdr),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -58,7 +60,7 @@ func ParseMessage(buf []byte) (msg *Message, rest []byte, ok bool) {
|
|||
return
|
||||
}
|
||||
var hdr linux.NetlinkMessageHeader
|
||||
binary.Unmarshal(hdrBytes, hostarch.ByteOrder, &hdr)
|
||||
hdr.UnmarshalUnsafe(hdrBytes)
|
||||
|
||||
// Msg portion.
|
||||
totalMsgLen := int(hdr.Length)
|
||||
|
@ -92,7 +94,7 @@ func (m *Message) Header() linux.NetlinkMessageHeader {
|
|||
|
||||
// GetData unmarshals the payload message header from this netlink message, and
|
||||
// returns the attributes portion.
|
||||
func (m *Message) GetData(msg interface{}) (AttrsView, bool) {
|
||||
func (m *Message) GetData(msg marshal.Marshallable) (AttrsView, bool) {
|
||||
b := BytesView(m.buf)
|
||||
|
||||
_, ok := b.Extract(linux.NetlinkMessageHeaderSize)
|
||||
|
@ -100,12 +102,12 @@ func (m *Message) GetData(msg interface{}) (AttrsView, bool) {
|
|||
return nil, false
|
||||
}
|
||||
|
||||
size := int(binary.Size(msg))
|
||||
size := msg.SizeBytes()
|
||||
msgBytes, ok := b.Extract(size)
|
||||
if !ok {
|
||||
return nil, false
|
||||
}
|
||||
binary.Unmarshal(msgBytes, hostarch.ByteOrder, msg)
|
||||
msg.UnmarshalUnsafe(msgBytes)
|
||||
|
||||
numPad := alignPad(linux.NetlinkMessageHeaderSize+size, linux.NLMSG_ALIGNTO)
|
||||
// Linux permits the last message not being aligned, just consume all of it.
|
||||
|
@ -131,7 +133,7 @@ func (m *Message) Finalize() []byte {
|
|||
// Align the message. Note that the message length in the header (set
|
||||
// above) is the useful length of the message, not the total aligned
|
||||
// length. See net/netlink/af_netlink.c:__nlmsg_put.
|
||||
aligned := binary.AlignUp(len(m.buf), linux.NLMSG_ALIGNTO)
|
||||
aligned := bits.AlignUp(len(m.buf), linux.NLMSG_ALIGNTO)
|
||||
m.putZeros(aligned - len(m.buf))
|
||||
return m.buf
|
||||
}
|
||||
|
@ -145,45 +147,45 @@ func (m *Message) putZeros(n int) {
|
|||
}
|
||||
|
||||
// Put serializes v into the message.
|
||||
func (m *Message) Put(v interface{}) {
|
||||
m.buf = binary.Marshal(m.buf, hostarch.ByteOrder, v)
|
||||
func (m *Message) Put(v marshal.Marshallable) {
|
||||
m.buf = append(m.buf, marshal.Marshal(v)...)
|
||||
}
|
||||
|
||||
// PutAttr adds v to the message as a netlink attribute.
|
||||
//
|
||||
// Preconditions: The serialized attribute (linux.NetlinkAttrHeaderSize +
|
||||
// binary.Size(v) fits in math.MaxUint16 bytes.
|
||||
func (m *Message) PutAttr(atype uint16, v interface{}) {
|
||||
l := linux.NetlinkAttrHeaderSize + int(binary.Size(v))
|
||||
// v.SizeBytes()) fits in math.MaxUint16 bytes.
|
||||
func (m *Message) PutAttr(atype uint16, v marshal.Marshallable) {
|
||||
l := linux.NetlinkAttrHeaderSize + v.SizeBytes()
|
||||
if l > math.MaxUint16 {
|
||||
panic(fmt.Sprintf("attribute too large: %d", l))
|
||||
}
|
||||
|
||||
m.Put(linux.NetlinkAttrHeader{
|
||||
m.Put(&linux.NetlinkAttrHeader{
|
||||
Type: atype,
|
||||
Length: uint16(l),
|
||||
})
|
||||
m.Put(v)
|
||||
|
||||
// Align the attribute.
|
||||
aligned := binary.AlignUp(l, linux.NLA_ALIGNTO)
|
||||
aligned := bits.AlignUp(l, linux.NLA_ALIGNTO)
|
||||
m.putZeros(aligned - l)
|
||||
}
|
||||
|
||||
// PutAttrString adds s to the message as a netlink attribute.
|
||||
func (m *Message) PutAttrString(atype uint16, s string) {
|
||||
l := linux.NetlinkAttrHeaderSize + len(s) + 1
|
||||
m.Put(linux.NetlinkAttrHeader{
|
||||
m.Put(&linux.NetlinkAttrHeader{
|
||||
Type: atype,
|
||||
Length: uint16(l),
|
||||
})
|
||||
|
||||
// String + NUL-termination.
|
||||
m.Put([]byte(s))
|
||||
m.Put(primitive.AsByteSlice([]byte(s)))
|
||||
m.putZeros(1)
|
||||
|
||||
// Align the attribute.
|
||||
aligned := binary.AlignUp(l, linux.NLA_ALIGNTO)
|
||||
aligned := bits.AlignUp(l, linux.NLA_ALIGNTO)
|
||||
m.putZeros(aligned - l)
|
||||
}
|
||||
|
||||
|
@ -251,7 +253,7 @@ func (v AttrsView) ParseFirst() (hdr linux.NetlinkAttrHeader, value []byte, rest
|
|||
if !ok {
|
||||
return
|
||||
}
|
||||
binary.Unmarshal(hdrBytes, hostarch.ByteOrder, &hdr)
|
||||
hdr.UnmarshalUnsafe(hdrBytes)
|
||||
|
||||
value, ok = b.Extract(int(hdr.Length) - linux.NetlinkAttrHeaderSize)
|
||||
if !ok {
|
||||
|
|
|
@ -20,13 +20,31 @@ import (
|
|||
"testing"
|
||||
|
||||
"gvisor.dev/gvisor/pkg/abi/linux"
|
||||
"gvisor.dev/gvisor/pkg/marshal"
|
||||
"gvisor.dev/gvisor/pkg/marshal/primitive"
|
||||
"gvisor.dev/gvisor/pkg/sentry/socket/netlink"
|
||||
)
|
||||
|
||||
type dummyNetlinkMsg struct {
|
||||
marshal.StubMarshallable
|
||||
Foo uint16
|
||||
}
|
||||
|
||||
func (*dummyNetlinkMsg) SizeBytes() int {
|
||||
return 2
|
||||
}
|
||||
|
||||
func (m *dummyNetlinkMsg) MarshalUnsafe(dst []byte) {
|
||||
p := primitive.Uint16(m.Foo)
|
||||
p.MarshalUnsafe(dst)
|
||||
}
|
||||
|
||||
func (m *dummyNetlinkMsg) UnmarshalUnsafe(src []byte) {
|
||||
var p primitive.Uint16
|
||||
p.UnmarshalUnsafe(src)
|
||||
m.Foo = uint16(p)
|
||||
}
|
||||
|
||||
func TestParseMessage(t *testing.T) {
|
||||
tests := []struct {
|
||||
desc string
|
||||
|
|
|
@ -11,6 +11,7 @@ go_library(
|
|||
deps = [
|
||||
"//pkg/abi/linux",
|
||||
"//pkg/context",
|
||||
"//pkg/marshal/primitive",
|
||||
"//pkg/sentry/inet",
|
||||
"//pkg/sentry/kernel",
|
||||
"//pkg/sentry/kernel/auth",
|
||||
|
|
|
@ -21,6 +21,7 @@ import (
|
|||
"golang.org/x/sys/unix"
|
||||
"gvisor.dev/gvisor/pkg/abi/linux"
|
||||
"gvisor.dev/gvisor/pkg/context"
|
||||
"gvisor.dev/gvisor/pkg/marshal/primitive"
|
||||
"gvisor.dev/gvisor/pkg/sentry/inet"
|
||||
"gvisor.dev/gvisor/pkg/sentry/kernel"
|
||||
"gvisor.dev/gvisor/pkg/sentry/kernel/auth"
|
||||
|
@ -167,7 +168,7 @@ func addNewLinkMessage(ms *netlink.MessageSet, idx int32, i inet.Interface) {
|
|||
Type: linux.RTM_NEWLINK,
|
||||
})
|
||||
|
||||
m.Put(linux.InterfaceInfoMessage{
|
||||
m.Put(&linux.InterfaceInfoMessage{
|
||||
Family: linux.AF_UNSPEC,
|
||||
Type: i.DeviceType,
|
||||
Index: idx,
|
||||
|
@ -175,7 +176,7 @@ func addNewLinkMessage(ms *netlink.MessageSet, idx int32, i inet.Interface) {
|
|||
})
|
||||
|
||||
m.PutAttrString(linux.IFLA_IFNAME, i.Name)
|
||||
m.PutAttr(linux.IFLA_MTU, i.MTU)
|
||||
m.PutAttr(linux.IFLA_MTU, primitive.AllocateUint32(i.MTU))
|
||||
|
||||
mac := make([]byte, 6)
|
||||
brd := mac
|
||||
|
@ -183,8 +184,8 @@ func addNewLinkMessage(ms *netlink.MessageSet, idx int32, i inet.Interface) {
|
|||
mac = i.Addr
|
||||
brd = bytes.Repeat([]byte{0xff}, len(i.Addr))
|
||||
}
|
||||
m.PutAttr(linux.IFLA_ADDRESS, mac)
|
||||
m.PutAttr(linux.IFLA_BROADCAST, brd)
|
||||
m.PutAttr(linux.IFLA_ADDRESS, primitive.AsByteSlice(mac))
|
||||
m.PutAttr(linux.IFLA_BROADCAST, primitive.AsByteSlice(brd))
|
||||
|
||||
// TODO(gvisor.dev/issue/578): There are many more attributes.
|
||||
}
|
||||
|
@ -216,14 +217,15 @@ func (p *Protocol) dumpAddrs(ctx context.Context, msg *netlink.Message, ms *netl
|
|||
Type: linux.RTM_NEWADDR,
|
||||
})
|
||||
|
||||
m.Put(linux.InterfaceAddrMessage{
|
||||
m.Put(&linux.InterfaceAddrMessage{
|
||||
Family: a.Family,
|
||||
PrefixLen: a.PrefixLen,
|
||||
Index: uint32(id),
|
||||
})
|
||||
|
||||
m.PutAttr(linux.IFA_LOCAL, []byte(a.Addr))
|
||||
m.PutAttr(linux.IFA_ADDRESS, []byte(a.Addr))
|
||||
addr := primitive.ByteSlice([]byte(a.Addr))
|
||||
m.PutAttr(linux.IFA_LOCAL, &addr)
|
||||
m.PutAttr(linux.IFA_ADDRESS, &addr)
|
||||
|
||||
// TODO(gvisor.dev/issue/578): There are many more attributes.
|
||||
}
|
||||
|
@ -366,7 +368,7 @@ func (p *Protocol) dumpRoutes(ctx context.Context, msg *netlink.Message, ms *net
|
|||
Type: linux.RTM_NEWROUTE,
|
||||
})
|
||||
|
||||
m.Put(linux.RouteMessage{
|
||||
m.Put(&linux.RouteMessage{
|
||||
Family: rt.Family,
|
||||
DstLen: rt.DstLen,
|
||||
SrcLen: rt.SrcLen,
|
||||
|
@ -382,18 +384,18 @@ func (p *Protocol) dumpRoutes(ctx context.Context, msg *netlink.Message, ms *net
|
|||
Flags: rt.Flags,
|
||||
})
|
||||
|
||||
m.PutAttr(254, []byte{123})
|
||||
m.PutAttr(254, primitive.AsByteSlice([]byte{123}))
|
||||
if rt.DstLen > 0 {
|
||||
m.PutAttr(linux.RTA_DST, rt.DstAddr)
|
||||
m.PutAttr(linux.RTA_DST, primitive.AsByteSlice(rt.DstAddr))
|
||||
}
|
||||
if rt.SrcLen > 0 {
|
||||
m.PutAttr(linux.RTA_SRC, rt.SrcAddr)
|
||||
m.PutAttr(linux.RTA_SRC, primitive.AsByteSlice(rt.SrcAddr))
|
||||
}
|
||||
if rt.OutputInterface != 0 {
|
||||
m.PutAttr(linux.RTA_OIF, rt.OutputInterface)
|
||||
m.PutAttr(linux.RTA_OIF, primitive.AllocateInt32(rt.OutputInterface))
|
||||
}
|
||||
if len(rt.GatewayAddr) > 0 {
|
||||
m.PutAttr(linux.RTA_GATEWAY, rt.GatewayAddr)
|
||||
m.PutAttr(linux.RTA_GATEWAY, primitive.AsByteSlice(rt.GatewayAddr))
|
||||
}
|
||||
|
||||
// TODO(gvisor.dev/issue/578): There are many more attributes.
|
||||
|
@ -503,7 +505,7 @@ func (p *Protocol) ProcessMessage(ctx context.Context, msg *netlink.Message, ms
|
|||
hdr := msg.Header()
|
||||
|
||||
// All messages start with a 1 byte protocol family.
|
||||
var family uint8
|
||||
var family primitive.Uint8
|
||||
if _, ok := msg.GetData(&family); !ok {
|
||||
// Linux ignores messages missing the protocol family. See
|
||||
// net/core/rtnetlink.c:rtnetlink_rcv_msg.
|
||||
|
|
|
@ -20,7 +20,6 @@ import (
|
|||
"math"
|
||||
|
||||
"gvisor.dev/gvisor/pkg/abi/linux"
|
||||
"gvisor.dev/gvisor/pkg/binary"
|
||||
"gvisor.dev/gvisor/pkg/context"
|
||||
"gvisor.dev/gvisor/pkg/hostarch"
|
||||
"gvisor.dev/gvisor/pkg/marshal"
|
||||
|
@ -223,7 +222,7 @@ func ExtractSockAddr(b []byte) (*linux.SockAddrNetlink, *syserr.Error) {
|
|||
}
|
||||
|
||||
var sa linux.SockAddrNetlink
|
||||
binary.Unmarshal(b[:linux.SockAddrNetlinkSize], hostarch.ByteOrder, &sa)
|
||||
sa.UnmarshalUnsafe(b[:sa.SizeBytes()])
|
||||
|
||||
if sa.Family != linux.AF_NETLINK {
|
||||
return nil, syserr.ErrInvalidArgument
|
||||
|
@ -338,16 +337,14 @@ func (s *socketOpsCommon) GetSockOpt(t *kernel.Task, level int, name int, outPtr
|
|||
}
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
sendBufferSizeP := primitive.Int32(s.sendBufferSize)
|
||||
return &sendBufferSizeP, nil
|
||||
return primitive.AllocateInt32(int32(s.sendBufferSize)), nil
|
||||
|
||||
case linux.SO_RCVBUF:
|
||||
if outLen < sizeOfInt32 {
|
||||
return nil, syserr.ErrInvalidArgument
|
||||
}
|
||||
// We don't have limit on receiving size.
|
||||
recvBufferSizeP := primitive.Int32(math.MaxInt32)
|
||||
return &recvBufferSizeP, nil
|
||||
return primitive.AllocateInt32(math.MaxInt32), nil
|
||||
|
||||
case linux.SO_PASSCRED:
|
||||
if outLen < sizeOfInt32 {
|
||||
|
@ -484,7 +481,7 @@ func (s *socketOpsCommon) GetSockName(t *kernel.Task) (linux.SockAddr, uint32, *
|
|||
Family: linux.AF_NETLINK,
|
||||
PortID: uint32(s.portID),
|
||||
}
|
||||
return sa, uint32(binary.Size(sa)), nil
|
||||
return sa, uint32(sa.SizeBytes()), nil
|
||||
}
|
||||
|
||||
// GetPeerName implements socket.Socket.GetPeerName.
|
||||
|
@ -495,7 +492,7 @@ func (s *socketOpsCommon) GetPeerName(t *kernel.Task) (linux.SockAddr, uint32, *
|
|||
// must be the kernel.
|
||||
PortID: 0,
|
||||
}
|
||||
return sa, uint32(binary.Size(sa)), nil
|
||||
return sa, uint32(sa.SizeBytes()), nil
|
||||
}
|
||||
|
||||
// RecvMsg implements socket.Socket.RecvMsg.
|
||||
|
@ -504,7 +501,7 @@ func (s *socketOpsCommon) RecvMsg(t *kernel.Task, dst usermem.IOSequence, flags
|
|||
Family: linux.AF_NETLINK,
|
||||
PortID: 0,
|
||||
}
|
||||
fromLen := uint32(binary.Size(from))
|
||||
fromLen := uint32(from.SizeBytes())
|
||||
|
||||
trunc := flags&linux.MSG_TRUNC != 0
|
||||
|
||||
|
@ -640,7 +637,7 @@ func (s *socketOpsCommon) sendResponse(ctx context.Context, ms *MessageSet) *sys
|
|||
})
|
||||
|
||||
// Add the dump_done_errno payload.
|
||||
m.Put(int64(0))
|
||||
m.Put(primitive.AllocateInt64(0))
|
||||
|
||||
_, notify, err := s.connection.Send(ctx, [][]byte{m.Finalize()}, cms, tcpip.FullAddress{})
|
||||
if err != nil && err != syserr.ErrWouldBlock {
|
||||
|
@ -658,7 +655,7 @@ func dumpErrorMesage(hdr linux.NetlinkMessageHeader, ms *MessageSet, err *syserr
|
|||
m := ms.AddMessage(linux.NetlinkMessageHeader{
|
||||
Type: linux.NLMSG_ERROR,
|
||||
})
|
||||
m.Put(linux.NetlinkErrorMessage{
|
||||
m.Put(&linux.NetlinkErrorMessage{
|
||||
Error: int32(-err.ToLinux().Number()),
|
||||
Header: hdr,
|
||||
})
|
||||
|
@ -668,7 +665,7 @@ func dumpAckMesage(hdr linux.NetlinkMessageHeader, ms *MessageSet) {
|
|||
m := ms.AddMessage(linux.NetlinkMessageHeader{
|
||||
Type: linux.NLMSG_ERROR,
|
||||
})
|
||||
m.Put(linux.NetlinkErrorMessage{
|
||||
m.Put(&linux.NetlinkErrorMessage{
|
||||
Error: 0,
|
||||
Header: hdr,
|
||||
})
|
||||
|
|
|
@ -19,7 +19,6 @@ go_library(
|
|||
],
|
||||
deps = [
|
||||
"//pkg/abi/linux",
|
||||
"//pkg/binary",
|
||||
"//pkg/context",
|
||||
"//pkg/hostarch",
|
||||
"//pkg/log",
|
||||
|
|
|
@ -26,6 +26,7 @@ package netstack
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
|
@ -35,7 +36,6 @@ import (
|
|||
|
||||
"golang.org/x/sys/unix"
|
||||
"gvisor.dev/gvisor/pkg/abi/linux"
|
||||
"gvisor.dev/gvisor/pkg/binary"
|
||||
"gvisor.dev/gvisor/pkg/context"
|
||||
"gvisor.dev/gvisor/pkg/hostarch"
|
||||
"gvisor.dev/gvisor/pkg/log"
|
||||
|
@ -375,9 +375,9 @@ func New(t *kernel.Task, family int, skType linux.SockType, protocol int, queue
|
|||
}), nil
|
||||
}
|
||||
|
||||
var sockAddrInetSize = int(binary.Size(linux.SockAddrInet{}))
|
||||
var sockAddrInet6Size = int(binary.Size(linux.SockAddrInet6{}))
|
||||
var sockAddrLinkSize = int(binary.Size(linux.SockAddrLink{}))
|
||||
var sockAddrInetSize = (*linux.SockAddrInet)(nil).SizeBytes()
|
||||
var sockAddrInet6Size = (*linux.SockAddrInet6)(nil).SizeBytes()
|
||||
var sockAddrLinkSize = (*linux.SockAddrLink)(nil).SizeBytes()
|
||||
|
||||
// bytesToIPAddress converts an IPv4 or IPv6 address from the user to the
|
||||
// netstack representation taking any addresses into account.
|
||||
|
@ -613,7 +613,7 @@ func (s *socketOpsCommon) Bind(t *kernel.Task, sockaddr []byte) *syserr.Error {
|
|||
if len(sockaddr) < sockAddrLinkSize {
|
||||
return syserr.ErrInvalidArgument
|
||||
}
|
||||
binary.Unmarshal(sockaddr[:sockAddrLinkSize], hostarch.ByteOrder, &a)
|
||||
a.UnmarshalBytes(sockaddr[:sockAddrLinkSize])
|
||||
|
||||
if a.Protocol != uint16(s.protocol) {
|
||||
return syserr.ErrInvalidArgument
|
||||
|
@ -1312,7 +1312,7 @@ func getSockOptIPv6(t *kernel.Task, s socket.SocketOps, ep commonEndpoint, name
|
|||
return &v, nil
|
||||
|
||||
case linux.IP6T_ORIGINAL_DST:
|
||||
if outLen < int(binary.Size(linux.SockAddrInet6{})) {
|
||||
if outLen < sockAddrInet6Size {
|
||||
return nil, syserr.ErrInvalidArgument
|
||||
}
|
||||
|
||||
|
@ -1509,7 +1509,7 @@ func getSockOptIP(t *kernel.Task, s socket.SocketOps, ep commonEndpoint, name in
|
|||
return &v, nil
|
||||
|
||||
case linux.SO_ORIGINAL_DST:
|
||||
if outLen < int(binary.Size(linux.SockAddrInet{})) {
|
||||
if outLen < sockAddrInetSize {
|
||||
return nil, syserr.ErrInvalidArgument
|
||||
}
|
||||
|
||||
|
@ -1742,7 +1742,7 @@ func setSockOptSocket(t *kernel.Task, s socket.SocketOps, ep commonEndpoint, nam
|
|||
}
|
||||
|
||||
var v linux.Timeval
|
||||
binary.Unmarshal(optVal[:linux.SizeOfTimeval], hostarch.ByteOrder, &v)
|
||||
v.UnmarshalBytes(optVal[:linux.SizeOfTimeval])
|
||||
if v.Usec < 0 || v.Usec >= int64(time.Second/time.Microsecond) {
|
||||
return syserr.ErrDomain
|
||||
}
|
||||
|
@ -1755,7 +1755,7 @@ func setSockOptSocket(t *kernel.Task, s socket.SocketOps, ep commonEndpoint, nam
|
|||
}
|
||||
|
||||
var v linux.Timeval
|
||||
binary.Unmarshal(optVal[:linux.SizeOfTimeval], hostarch.ByteOrder, &v)
|
||||
v.UnmarshalBytes(optVal[:linux.SizeOfTimeval])
|
||||
if v.Usec < 0 || v.Usec >= int64(time.Second/time.Microsecond) {
|
||||
return syserr.ErrDomain
|
||||
}
|
||||
|
@ -1791,7 +1791,11 @@ func setSockOptSocket(t *kernel.Task, s socket.SocketOps, ep commonEndpoint, nam
|
|||
}
|
||||
|
||||
var v linux.Linger
|
||||
binary.Unmarshal(optVal[:linux.SizeOfLinger], hostarch.ByteOrder, &v)
|
||||
v.UnmarshalBytes(optVal[:linux.SizeOfLinger])
|
||||
|
||||
if v != (linux.Linger{}) {
|
||||
socket.SetSockOptEmitUnimplementedEvent(t, name)
|
||||
}
|
||||
|
||||
ep.SocketOptions().SetLinger(tcpip.LingerOption{
|
||||
Enabled: v.OnOff != 0,
|
||||
|
@ -2090,9 +2094,9 @@ func setSockOptIPv6(t *kernel.Task, s socket.SocketOps, ep commonEndpoint, name
|
|||
}
|
||||
|
||||
var (
|
||||
inetMulticastRequestSize = int(binary.Size(linux.InetMulticastRequest{}))
|
||||
inetMulticastRequestWithNICSize = int(binary.Size(linux.InetMulticastRequestWithNIC{}))
|
||||
inet6MulticastRequestSize = int(binary.Size(linux.Inet6MulticastRequest{}))
|
||||
inetMulticastRequestSize = (*linux.InetMulticastRequest)(nil).SizeBytes()
|
||||
inetMulticastRequestWithNICSize = (*linux.InetMulticastRequestWithNIC)(nil).SizeBytes()
|
||||
inet6MulticastRequestSize = (*linux.Inet6MulticastRequest)(nil).SizeBytes()
|
||||
)
|
||||
|
||||
// copyInMulticastRequest copies in a variable-size multicast request. The
|
||||
|
@ -2117,12 +2121,12 @@ func copyInMulticastRequest(optVal []byte, allowAddr bool) (linux.InetMulticastR
|
|||
|
||||
if len(optVal) >= inetMulticastRequestWithNICSize {
|
||||
var req linux.InetMulticastRequestWithNIC
|
||||
binary.Unmarshal(optVal[:inetMulticastRequestWithNICSize], hostarch.ByteOrder, &req)
|
||||
req.UnmarshalUnsafe(optVal[:inetMulticastRequestWithNICSize])
|
||||
return req, nil
|
||||
}
|
||||
|
||||
var req linux.InetMulticastRequestWithNIC
|
||||
binary.Unmarshal(optVal[:inetMulticastRequestSize], hostarch.ByteOrder, &req.InetMulticastRequest)
|
||||
req.InetMulticastRequest.UnmarshalUnsafe(optVal[:inetMulticastRequestSize])
|
||||
return req, nil
|
||||
}
|
||||
|
||||
|
@ -2132,7 +2136,7 @@ func copyInMulticastV6Request(optVal []byte) (linux.Inet6MulticastRequest, *syse
|
|||
}
|
||||
|
||||
var req linux.Inet6MulticastRequest
|
||||
binary.Unmarshal(optVal[:inet6MulticastRequestSize], hostarch.ByteOrder, &req)
|
||||
req.UnmarshalUnsafe(optVal[:inet6MulticastRequestSize])
|
||||
return req, nil
|
||||
}
|
||||
|
||||
|
@ -3101,8 +3105,8 @@ func interfaceIoctl(ctx context.Context, io usermem.IO, arg int, ifr *linux.IFRe
|
|||
continue
|
||||
}
|
||||
// Populate ifr.ifr_netmask (type sockaddr).
|
||||
hostarch.ByteOrder.PutUint16(ifr.Data[0:2], uint16(linux.AF_INET))
|
||||
hostarch.ByteOrder.PutUint16(ifr.Data[2:4], 0)
|
||||
hostarch.ByteOrder.PutUint16(ifr.Data[0:], uint16(linux.AF_INET))
|
||||
hostarch.ByteOrder.PutUint16(ifr.Data[2:], 0)
|
||||
var mask uint32 = 0xffffffff << (32 - addr.PrefixLen)
|
||||
// Netmask is expected to be returned as a big endian
|
||||
// value.
|
||||
|
|
|
@ -24,7 +24,6 @@ import (
|
|||
|
||||
"golang.org/x/sys/unix"
|
||||
"gvisor.dev/gvisor/pkg/abi/linux"
|
||||
"gvisor.dev/gvisor/pkg/binary"
|
||||
"gvisor.dev/gvisor/pkg/context"
|
||||
"gvisor.dev/gvisor/pkg/hostarch"
|
||||
"gvisor.dev/gvisor/pkg/marshal"
|
||||
|
@ -572,19 +571,19 @@ func UnmarshalSockAddr(family int, data []byte) linux.SockAddr {
|
|||
switch family {
|
||||
case unix.AF_INET:
|
||||
var addr linux.SockAddrInet
|
||||
binary.Unmarshal(data[:unix.SizeofSockaddrInet4], hostarch.ByteOrder, &addr)
|
||||
addr.UnmarshalUnsafe(data[:addr.SizeBytes()])
|
||||
return &addr
|
||||
case unix.AF_INET6:
|
||||
var addr linux.SockAddrInet6
|
||||
binary.Unmarshal(data[:unix.SizeofSockaddrInet6], hostarch.ByteOrder, &addr)
|
||||
addr.UnmarshalUnsafe(data[:addr.SizeBytes()])
|
||||
return &addr
|
||||
case unix.AF_UNIX:
|
||||
var addr linux.SockAddrUnix
|
||||
binary.Unmarshal(data[:unix.SizeofSockaddrUnix], hostarch.ByteOrder, &addr)
|
||||
addr.UnmarshalUnsafe(data[:addr.SizeBytes()])
|
||||
return &addr
|
||||
case unix.AF_NETLINK:
|
||||
var addr linux.SockAddrNetlink
|
||||
binary.Unmarshal(data[:unix.SizeofSockaddrNetlink], hostarch.ByteOrder, &addr)
|
||||
addr.UnmarshalUnsafe(data[:addr.SizeBytes()])
|
||||
return &addr
|
||||
default:
|
||||
panic(fmt.Sprintf("Unsupported socket family %v", family))
|
||||
|
@ -716,7 +715,7 @@ func AddressAndFamily(addr []byte) (tcpip.FullAddress, uint16, *syserr.Error) {
|
|||
if len(addr) < sockAddrInetSize {
|
||||
return tcpip.FullAddress{}, family, syserr.ErrInvalidArgument
|
||||
}
|
||||
binary.Unmarshal(addr[:sockAddrInetSize], hostarch.ByteOrder, &a)
|
||||
a.UnmarshalUnsafe(addr[:sockAddrInetSize])
|
||||
|
||||
out := tcpip.FullAddress{
|
||||
Addr: BytesToIPAddress(a.Addr[:]),
|
||||
|
@ -729,7 +728,7 @@ func AddressAndFamily(addr []byte) (tcpip.FullAddress, uint16, *syserr.Error) {
|
|||
if len(addr) < sockAddrInet6Size {
|
||||
return tcpip.FullAddress{}, family, syserr.ErrInvalidArgument
|
||||
}
|
||||
binary.Unmarshal(addr[:sockAddrInet6Size], hostarch.ByteOrder, &a)
|
||||
a.UnmarshalUnsafe(addr[:sockAddrInet6Size])
|
||||
|
||||
out := tcpip.FullAddress{
|
||||
Addr: BytesToIPAddress(a.Addr[:]),
|
||||
|
@ -745,7 +744,7 @@ func AddressAndFamily(addr []byte) (tcpip.FullAddress, uint16, *syserr.Error) {
|
|||
if len(addr) < sockAddrLinkSize {
|
||||
return tcpip.FullAddress{}, family, syserr.ErrInvalidArgument
|
||||
}
|
||||
binary.Unmarshal(addr[:sockAddrLinkSize], hostarch.ByteOrder, &a)
|
||||
a.UnmarshalUnsafe(addr[:sockAddrLinkSize])
|
||||
if a.Family != linux.AF_PACKET || a.HardwareAddrLen != header.EthernetAddressSize {
|
||||
return tcpip.FullAddress{}, family, syserr.ErrInvalidArgument
|
||||
}
|
||||
|
|
|
@ -25,7 +25,6 @@ go_library(
|
|||
":strace_go_proto",
|
||||
"//pkg/abi",
|
||||
"//pkg/abi/linux",
|
||||
"//pkg/binary",
|
||||
"//pkg/bits",
|
||||
"//pkg/eventchannel",
|
||||
"//pkg/hostarch",
|
||||
|
|
|
@ -20,14 +20,13 @@ import (
|
|||
|
||||
"gvisor.dev/gvisor/pkg/abi"
|
||||
"gvisor.dev/gvisor/pkg/abi/linux"
|
||||
"gvisor.dev/gvisor/pkg/binary"
|
||||
"gvisor.dev/gvisor/pkg/bits"
|
||||
"gvisor.dev/gvisor/pkg/hostarch"
|
||||
"gvisor.dev/gvisor/pkg/marshal/primitive"
|
||||
"gvisor.dev/gvisor/pkg/sentry/kernel"
|
||||
"gvisor.dev/gvisor/pkg/sentry/socket"
|
||||
"gvisor.dev/gvisor/pkg/sentry/socket/netlink"
|
||||
slinux "gvisor.dev/gvisor/pkg/sentry/syscalls/linux"
|
||||
|
||||
"gvisor.dev/gvisor/pkg/hostarch"
|
||||
)
|
||||
|
||||
// SocketFamily are the possible socket(2) families.
|
||||
|
@ -162,6 +161,15 @@ var controlMessageType = map[int32]string{
|
|||
linux.SO_TIMESTAMP: "SO_TIMESTAMP",
|
||||
}
|
||||
|
||||
func unmarshalControlMessageRights(src []byte) linux.ControlMessageRights {
|
||||
count := len(src) / linux.SizeOfControlMessageRight
|
||||
cmr := make(linux.ControlMessageRights, count)
|
||||
for i, _ := range cmr {
|
||||
cmr[i] = int32(hostarch.ByteOrder.Uint32(src[i*linux.SizeOfControlMessageRight:]))
|
||||
}
|
||||
return cmr
|
||||
}
|
||||
|
||||
func cmsghdr(t *kernel.Task, addr hostarch.Addr, length uint64, maxBytes uint64) string {
|
||||
if length > maxBytes {
|
||||
return fmt.Sprintf("%#x (error decoding control: invalid length (%d))", addr, length)
|
||||
|
@ -181,7 +189,7 @@ func cmsghdr(t *kernel.Task, addr hostarch.Addr, length uint64, maxBytes uint64)
|
|||
}
|
||||
|
||||
var h linux.ControlMessageHeader
|
||||
binary.Unmarshal(buf[i:i+linux.SizeOfControlMessageHeader], hostarch.ByteOrder, &h)
|
||||
h.UnmarshalUnsafe(buf[i : i+linux.SizeOfControlMessageHeader])
|
||||
|
||||
var skipData bool
|
||||
level := "SOL_SOCKET"
|
||||
|
@ -221,18 +229,14 @@ func cmsghdr(t *kernel.Task, addr hostarch.Addr, length uint64, maxBytes uint64)
|
|||
|
||||
if skipData {
|
||||
strs = append(strs, fmt.Sprintf("{level=%s, type=%s, length=%d}", level, typ, h.Length))
|
||||
i += binary.AlignUp(length, width)
|
||||
i += bits.AlignUp(length, width)
|
||||
continue
|
||||
}
|
||||
|
||||
switch h.Type {
|
||||
case linux.SCM_RIGHTS:
|
||||
rightsSize := binary.AlignDown(length, linux.SizeOfControlMessageRight)
|
||||
|
||||
numRights := rightsSize / linux.SizeOfControlMessageRight
|
||||
fds := make(linux.ControlMessageRights, numRights)
|
||||
binary.Unmarshal(buf[i:i+rightsSize], hostarch.ByteOrder, &fds)
|
||||
|
||||
rightsSize := bits.AlignDown(length, linux.SizeOfControlMessageRight)
|
||||
fds := unmarshalControlMessageRights(buf[i : i+rightsSize])
|
||||
rights := make([]string, 0, len(fds))
|
||||
for _, fd := range fds {
|
||||
rights = append(rights, fmt.Sprint(fd))
|
||||
|
@ -258,7 +262,7 @@ func cmsghdr(t *kernel.Task, addr hostarch.Addr, length uint64, maxBytes uint64)
|
|||
}
|
||||
|
||||
var creds linux.ControlMessageCredentials
|
||||
binary.Unmarshal(buf[i:i+linux.SizeOfControlMessageCredentials], hostarch.ByteOrder, &creds)
|
||||
creds.UnmarshalUnsafe(buf[i : i+linux.SizeOfControlMessageCredentials])
|
||||
|
||||
strs = append(strs, fmt.Sprintf(
|
||||
"{level=%s, type=%s, length=%d, pid: %d, uid: %d, gid: %d}",
|
||||
|
@ -282,7 +286,7 @@ func cmsghdr(t *kernel.Task, addr hostarch.Addr, length uint64, maxBytes uint64)
|
|||
}
|
||||
|
||||
var tv linux.Timeval
|
||||
binary.Unmarshal(buf[i:i+linux.SizeOfTimeval], hostarch.ByteOrder, &tv)
|
||||
tv.UnmarshalUnsafe(buf[i : i+linux.SizeOfTimeval])
|
||||
|
||||
strs = append(strs, fmt.Sprintf(
|
||||
"{level=%s, type=%s, length=%d, Sec: %d, Usec: %d}",
|
||||
|
@ -296,7 +300,7 @@ func cmsghdr(t *kernel.Task, addr hostarch.Addr, length uint64, maxBytes uint64)
|
|||
default:
|
||||
panic("unreachable")
|
||||
}
|
||||
i += binary.AlignUp(length, width)
|
||||
i += bits.AlignUp(length, width)
|
||||
}
|
||||
|
||||
return fmt.Sprintf("%#x %s", addr, strings.Join(strs, ", "))
|
||||
|
|
|
@ -463,8 +463,7 @@ func GetSockOpt(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.Sy
|
|||
return 0, nil, e.ToError()
|
||||
}
|
||||
|
||||
vLen := int32(v.SizeBytes())
|
||||
if _, err := primitive.CopyInt32Out(t, optLenAddr, vLen); err != nil {
|
||||
if _, err := primitive.CopyInt32Out(t, optLenAddr, int32(v.SizeBytes())); err != nil {
|
||||
return 0, nil, err
|
||||
}
|
||||
|
||||
|
|
|
@ -467,8 +467,7 @@ func GetSockOpt(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.Sy
|
|||
return 0, nil, e.ToError()
|
||||
}
|
||||
|
||||
vLen := int32(v.SizeBytes())
|
||||
if _, err := primitive.CopyInt32Out(t, optLenAddr, vLen); err != nil {
|
||||
if _, err := primitive.CopyInt32Out(t, optLenAddr, int32(v.SizeBytes())); err != nil {
|
||||
return 0, nil, err
|
||||
}
|
||||
|
||||
|
|
|
@ -14,7 +14,6 @@ go_library(
|
|||
],
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//pkg/binary",
|
||||
"//pkg/iovec",
|
||||
"//pkg/sync",
|
||||
"//pkg/tcpip",
|
||||
|
|
|
@ -45,7 +45,6 @@ import (
|
|||
"sync/atomic"
|
||||
|
||||
"golang.org/x/sys/unix"
|
||||
"gvisor.dev/gvisor/pkg/binary"
|
||||
"gvisor.dev/gvisor/pkg/iovec"
|
||||
"gvisor.dev/gvisor/pkg/sync"
|
||||
"gvisor.dev/gvisor/pkg/tcpip"
|
||||
|
@ -403,6 +402,35 @@ type virtioNetHdr struct {
|
|||
csumOffset uint16
|
||||
}
|
||||
|
||||
// marshal serializes h to a newly-allocated byte slice, in little-endian byte
|
||||
// order.
|
||||
//
|
||||
// Note: Virtio v1.0 onwards specifies little-endian as the byte ordering used
|
||||
// for general serialization. This makes it difficult to use go-marshal for
|
||||
// virtio types, as go-marshal implicitly uses the native byte ordering.
|
||||
func (h *virtioNetHdr) marshal() []byte {
|
||||
buf := [virtioNetHdrSize]byte{
|
||||
0: byte(h.flags),
|
||||
1: byte(h.gsoType),
|
||||
|
||||
// Manually lay out the fields in little-endian byte order. Little endian =>
|
||||
// least significant bit goes to the lower address.
|
||||
|
||||
2: byte(h.hdrLen),
|
||||
3: byte(h.hdrLen >> 8),
|
||||
|
||||
4: byte(h.gsoSize),
|
||||
5: byte(h.gsoSize >> 8),
|
||||
|
||||
6: byte(h.csumStart),
|
||||
7: byte(h.csumStart >> 8),
|
||||
|
||||
8: byte(h.csumOffset),
|
||||
9: byte(h.csumOffset >> 8),
|
||||
}
|
||||
return buf[:]
|
||||
}
|
||||
|
||||
// These constants are declared in linux/virtio_net.h.
|
||||
const (
|
||||
_VIRTIO_NET_HDR_F_NEEDS_CSUM = 1
|
||||
|
@ -463,7 +491,7 @@ func (e *endpoint) WritePacket(r stack.RouteInfo, protocol tcpip.NetworkProtocol
|
|||
}
|
||||
}
|
||||
|
||||
vnetHdrBuf := binary.Marshal(make([]byte, 0, virtioNetHdrSize), binary.LittleEndian, vnetHdr)
|
||||
vnetHdrBuf := vnetHdr.marshal()
|
||||
builder.Add(vnetHdrBuf)
|
||||
}
|
||||
|
||||
|
@ -503,7 +531,7 @@ func (e *endpoint) sendBatch(batchFD int, batch []*stack.PacketBuffer) (int, tcp
|
|||
vnetHdr.gsoSize = pkt.GSOOptions.MSS
|
||||
}
|
||||
}
|
||||
vnetHdrBuf = binary.Marshal(make([]byte, 0, virtioNetHdrSize), binary.LittleEndian, vnetHdr)
|
||||
vnetHdrBuf = vnetHdr.marshal()
|
||||
}
|
||||
|
||||
var builder iovec.Builder
|
||||
|
|
|
@ -1107,6 +1107,7 @@ const (
|
|||
// LingerOption is used by SetSockOpt/GetSockOpt to set/get the
|
||||
// duration for which a socket lingers before returning from Close.
|
||||
//
|
||||
// +marshal
|
||||
// +stateify savable
|
||||
type LingerOption struct {
|
||||
Enabled bool
|
||||
|
|
Loading…
Reference in New Issue