Remove uses of the binary package from the rest of the sentry.

PiperOrigin-RevId: 372020696
This commit is contained in:
Rahat Mahmood
2021-05-04 16:41:08 -07:00
committed by gVisor bot
parent d496c285aa
commit e00bd82816
17 changed files with 141 additions and 75 deletions
-4
View File
@@ -76,7 +76,6 @@ go_library(
visibility = ["//visibility:public"],
deps = [
"//pkg/abi",
"//pkg/binary",
"//pkg/bits",
"//pkg/marshal",
"//pkg/marshal/primitive",
@@ -88,7 +87,4 @@ go_test(
size = "small",
srcs = ["netfilter_test.go"],
library = ":linux",
deps = [
"//pkg/binary",
],
)
+50
View File
@@ -106,3 +106,53 @@ const (
// NT_ARM_TLS is for ARM TLS register.
NT_ARM_TLS = 0x401
)
// ElfHeader64 is the ELF64 file header.
//
// +marshal
type ElfHeader64 struct {
Ident [16]byte // File identification.
Type uint16 // File type.
Machine uint16 // Machine architecture.
Version uint32 // ELF format version.
Entry uint64 // Entry point.
Phoff uint64 // Program header file offset.
Shoff uint64 // Section header file offset.
Flags uint32 // Architecture-specific flags.
Ehsize uint16 // Size of ELF header in bytes.
Phentsize uint16 // Size of program header entry.
Phnum uint16 // Number of program header entries.
Shentsize uint16 // Size of section header entry.
Shnum uint16 // Number of section header entries.
Shstrndx uint16 // Section name strings section.
}
// ElfSection64 is the ELF64 Section header.
//
// +marshal
type ElfSection64 struct {
Name uint32 // Section name (index into the section header string table).
Type uint32 // Section type.
Flags uint64 // Section flags.
Addr uint64 // Address in memory image.
Off uint64 // Offset in file.
Size uint64 // Size in bytes.
Link uint32 // Index of a related section.
Info uint32 // Depends on section type.
Addralign uint64 // Alignment in bytes.
Entsize uint64 // Size of each entry in section.
}
// ElfProg64 is the ELF64 Program header.
//
// +marshal
type ElfProg64 struct {
Type uint32 // Entry type.
Flags uint32 // Access permission flags.
Off uint64 // File offset of contents.
Vaddr uint64 // Virtual address in memory image.
Paddr uint64 // Physical address (not used).
Filesz uint64 // Size of contents in file.
Memsz uint64 // Size of contents in memory.
Align uint64 // Alignment in memory and file.
}
+1 -5
View File
@@ -14,10 +14,6 @@
package linux
import (
"gvisor.dev/gvisor/pkg/binary"
)
// Event masks.
const (
EPOLLIN = 0x1
@@ -59,4 +55,4 @@ const (
)
// SizeOfEpollEvent is the size of EpollEvent struct.
var SizeOfEpollEvent = int(binary.Size(EpollEvent{}))
var SizeOfEpollEvent = (*EpollEvent)(nil).SizeBytes()
+2 -3
View File
@@ -19,7 +19,6 @@ import (
"strings"
"gvisor.dev/gvisor/pkg/abi"
"gvisor.dev/gvisor/pkg/binary"
)
// Constants for open(2).
@@ -201,7 +200,7 @@ const (
)
// SizeOfStat is the size of a Stat struct.
var SizeOfStat = binary.Size(Stat{})
var SizeOfStat = (*Stat)(nil).SizeBytes()
// Flags for statx.
const (
@@ -268,7 +267,7 @@ type Statx struct {
}
// SizeOfStatx is the size of a Statx struct.
var SizeOfStatx = binary.Size(Statx{})
var SizeOfStatx = (*Statx)(nil).SizeBytes()
// FileMode represents a mode_t.
type FileMode uint16
+1 -3
View File
@@ -14,8 +14,6 @@
package linux
import "gvisor.dev/gvisor/pkg/binary"
const (
// IFNAMSIZ is the size of the name field for IFReq.
IFNAMSIZ = 16
@@ -66,7 +64,7 @@ func (ifr *IFReq) SetName(name string) {
}
// SizeOfIFReq is the binary size of an IFReq struct (40 bytes).
var SizeOfIFReq = binary.Size(IFReq{})
var SizeOfIFReq = (*IFReq)(nil).SizeBytes()
// IFMap contains interface hardware parameters.
type IFMap struct {
+2 -3
View File
@@ -15,9 +15,8 @@
package linux
import (
"encoding/binary"
"testing"
"gvisor.dev/gvisor/pkg/binary"
)
func TestSizes(t *testing.T) {
@@ -42,7 +41,7 @@ func TestSizes(t *testing.T) {
}
for _, tc := range testCases {
if calculated := binary.Size(tc.typ); calculated != tc.defined {
if calculated := uintptr(binary.Size(tc.typ)); calculated != tc.defined {
t.Errorf("%T has a defined size of %d and calculated size of %d", tc.typ, tc.defined, calculated)
}
}
+2 -1
View File
@@ -26,6 +26,7 @@ go_test(
library = ":bpf",
deps = [
"//pkg/abi/linux",
"//pkg/binary",
"//pkg/hostarch",
"//pkg/marshal",
],
)
+11 -9
View File
@@ -15,10 +15,12 @@
package bpf
import (
"encoding/binary"
"testing"
"gvisor.dev/gvisor/pkg/abi/linux"
"gvisor.dev/gvisor/pkg/binary"
"gvisor.dev/gvisor/pkg/hostarch"
"gvisor.dev/gvisor/pkg/marshal"
)
func TestCompilationErrors(t *testing.T) {
@@ -750,29 +752,29 @@ func TestSimpleFilter(t *testing.T) {
// desc is the test's description.
desc string
// seccompData is the input data.
seccompData
// SeccompData is the input data.
data linux.SeccompData
// expectedRet is the expected return value of the BPF program.
expectedRet uint32
}{
{
desc: "Invalid arch is rejected",
seccompData: seccompData{nr: 1 /* x86 exit */, arch: 0x40000003 /* AUDIT_ARCH_I386 */},
data: linux.SeccompData{Nr: 1 /* x86 exit */, Arch: 0x40000003 /* AUDIT_ARCH_I386 */},
expectedRet: 0,
},
{
desc: "Disallowed syscall is rejected",
seccompData: seccompData{nr: 105 /* __NR_setuid */, arch: 0xc000003e},
data: linux.SeccompData{Nr: 105 /* __NR_setuid */, Arch: 0xc000003e},
expectedRet: 0,
},
{
desc: "Allowed syscall is indeed allowed",
seccompData: seccompData{nr: 231 /* __NR_exit_group */, arch: 0xc000003e},
data: linux.SeccompData{Nr: 231 /* __NR_exit_group */, Arch: 0xc000003e},
expectedRet: 0x7fff0000,
},
} {
ret, err := Exec(p, test.seccompData.asInput())
ret, err := Exec(p, dataAsInput(&test.data))
if err != nil {
t.Errorf("%s: expected return value of %d, got execution error: %v", test.desc, test.expectedRet, err)
continue
@@ -792,6 +794,6 @@ type seccompData struct {
}
// asInput converts a seccompData to a bpf.Input.
func (d *seccompData) asInput() Input {
return InputBytes{binary.Marshal(nil, binary.LittleEndian, d), binary.LittleEndian}
func dataAsInput(data *linux.SeccompData) Input {
return InputBytes{marshal.Marshal(data), hostarch.ByteOrder}
}
+1 -4
View File
@@ -6,10 +6,7 @@ go_library(
name = "compressio",
srcs = ["compressio.go"],
visibility = ["//:sandbox"],
deps = [
"//pkg/binary",
"//pkg/sync",
],
deps = ["//pkg/sync"],
)
go_test(
+30 -11
View File
@@ -48,12 +48,12 @@ import (
"compress/flate"
"crypto/hmac"
"crypto/sha256"
"encoding/binary"
"errors"
"hash"
"io"
"runtime"
"gvisor.dev/gvisor/pkg/binary"
"gvisor.dev/gvisor/pkg/sync"
)
@@ -130,6 +130,10 @@ type worker struct {
hashPool *hashPool
input chan *chunk
output chan result
// scratch is a temporary buffer used for marshalling. This is declared
// unfront here to avoid reallocation.
scratch [4]byte
}
// work is the main work routine; see worker.
@@ -167,7 +171,8 @@ func (w *worker) work(compress bool, level int) {
// Write the hash, if enabled.
if h != nil {
binary.WriteUint32(h, binary.BigEndian, uint32(c.compressed.Len()))
binary.BigEndian.PutUint32(w.scratch[:], uint32(c.compressed.Len()))
h.Write(w.scratch[:4])
c.h = h
h = nil
}
@@ -175,7 +180,8 @@ func (w *worker) work(compress bool, level int) {
// Check the hash of the compressed contents.
if h != nil {
h.Write(c.compressed.Bytes())
binary.WriteUint32(h, binary.BigEndian, uint32(c.compressed.Len()))
binary.BigEndian.PutUint32(w.scratch[:], uint32(c.compressed.Len()))
h.Write(w.scratch[:4])
io.CopyN(h, bytes.NewReader(c.lastSum), int64(len(c.lastSum)))
sum := h.Sum(nil)
@@ -352,6 +358,10 @@ type Reader struct {
// in is the source.
in io.Reader
// scratch is a temporary buffer used for marshalling. This is declared
// unfront here to avoid reallocation.
scratch [4]byte
}
var _ io.Reader = (*Reader)(nil)
@@ -368,14 +378,15 @@ func NewReader(in io.Reader, key []byte) (*Reader, error) {
// Use double buffering for read.
r.init(key, 2*runtime.GOMAXPROCS(0), false, 0)
var err error
if r.chunkSize, err = binary.ReadUint32(in, binary.BigEndian); err != nil {
if _, err := io.ReadFull(in, r.scratch[:4]); err != nil {
return nil, err
}
r.chunkSize = binary.BigEndian.Uint32(r.scratch[:4])
if r.hashPool != nil {
h := r.hashPool.getHash()
binary.WriteUint32(h, binary.BigEndian, r.chunkSize)
binary.BigEndian.PutUint32(r.scratch[:], r.chunkSize)
h.Write(r.scratch[:4])
r.lastSum = h.Sum(nil)
r.hashPool.putHash(h)
sum := make([]byte, len(r.lastSum))
@@ -467,8 +478,7 @@ func (r *Reader) Read(p []byte) (int, error) {
// reader. The length is used to limit the reader.
//
// See writer.flush.
l, err := binary.ReadUint32(r.in, binary.BigEndian)
if err != nil {
if _, err := io.ReadFull(r.in, r.scratch[:4]); err != nil {
// This is generally okay as long as there
// are still buffers outstanding. We actually
// just wait for completion of those buffers here
@@ -488,6 +498,7 @@ func (r *Reader) Read(p []byte) (int, error) {
return done, err
}
}
l := binary.BigEndian.Uint32(r.scratch[:4])
// Read this chunk and schedule decompression.
compressed := bufPool.Get().(*bytes.Buffer)
@@ -573,6 +584,10 @@ type Writer struct {
// closed indicates whether the file has been closed.
closed bool
// scratch is a temporary buffer used for marshalling. This is declared
// unfront here to avoid reallocation.
scratch [4]byte
}
var _ io.Writer = (*Writer)(nil)
@@ -594,13 +609,15 @@ func NewWriter(out io.Writer, key []byte, chunkSize uint32, level int) (*Writer,
}
w.init(key, 1+runtime.GOMAXPROCS(0), true, level)
if err := binary.WriteUint32(w.out, binary.BigEndian, chunkSize); err != nil {
binary.BigEndian.PutUint32(w.scratch[:], chunkSize)
if _, err := w.out.Write(w.scratch[:4]); err != nil {
return nil, err
}
if w.hashPool != nil {
h := w.hashPool.getHash()
binary.WriteUint32(h, binary.BigEndian, chunkSize)
binary.BigEndian.PutUint32(w.scratch[:], chunkSize)
h.Write(w.scratch[:4])
w.lastSum = h.Sum(nil)
w.hashPool.putHash(h)
if _, err := io.CopyN(w.out, bytes.NewReader(w.lastSum), int64(len(w.lastSum))); err != nil {
@@ -616,7 +633,9 @@ func (w *Writer) flush(c *chunk) error {
// Prefix each chunk with a length; this allows the reader to safely
// limit reads while buffering.
l := uint32(c.compressed.Len())
if err := binary.WriteUint32(w.out, binary.BigEndian, l); err != nil {
binary.BigEndian.PutUint32(w.scratch[:], l)
if _, err := w.out.Write(w.scratch[:4]); err != nil {
return err
}
-1
View File
@@ -46,7 +46,6 @@ go_library(
visibility = ["//pkg/sentry:internal"],
deps = [
"//pkg/abi/linux",
"//pkg/binary",
"//pkg/context",
"//pkg/fd",
"//pkg/fspath",
+2 -1
View File
@@ -11,11 +11,12 @@ go_library(
"vdso.go",
"vdso_state.go",
],
marshal = True,
marshal_debug = True,
visibility = ["//pkg/sentry:internal"],
deps = [
"//pkg/abi",
"//pkg/abi/linux",
"//pkg/binary",
"//pkg/context",
"//pkg/cpuid",
"//pkg/hostarch",
+6 -8
View File
@@ -22,7 +22,6 @@ import (
"gvisor.dev/gvisor/pkg/abi"
"gvisor.dev/gvisor/pkg/abi/linux"
"gvisor.dev/gvisor/pkg/binary"
"gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/cpuid"
"gvisor.dev/gvisor/pkg/hostarch"
@@ -47,10 +46,10 @@ const (
var (
// header64Size is the size of elf.Header64.
header64Size = int(binary.Size(elf.Header64{}))
header64Size = (*linux.ElfHeader64)(nil).SizeBytes()
// Prog64Size is the size of elf.Prog64.
prog64Size = int(binary.Size(elf.Prog64{}))
prog64Size = (*linux.ElfProg64)(nil).SizeBytes()
)
func progFlagsAsPerms(f elf.ProgFlag) hostarch.AccessType {
@@ -136,7 +135,6 @@ func parseHeader(ctx context.Context, f fullReader) (elfInfo, error) {
log.Infof("Unsupported ELF endianness: %v", endian)
return elfInfo{}, syserror.ENOEXEC
}
byteOrder := binary.LittleEndian
if version := elf.Version(ident[elf.EI_VERSION]); version != elf.EV_CURRENT {
log.Infof("Unsupported ELF version: %v", version)
@@ -145,7 +143,7 @@ func parseHeader(ctx context.Context, f fullReader) (elfInfo, error) {
// EI_OSABI is ignored by Linux, which is the only OS supported.
os := abi.Linux
var hdr elf.Header64
var hdr linux.ElfHeader64
hdrBuf := make([]byte, header64Size)
_, err = f.ReadFull(ctx, usermem.BytesIOSequence(hdrBuf), 0)
if err != nil {
@@ -156,7 +154,7 @@ func parseHeader(ctx context.Context, f fullReader) (elfInfo, error) {
}
return elfInfo{}, err
}
binary.Unmarshal(hdrBuf, byteOrder, &hdr)
hdr.UnmarshalUnsafe(hdrBuf)
// We support amd64 and arm64.
var a arch.Arch
@@ -213,8 +211,8 @@ func parseHeader(ctx context.Context, f fullReader) (elfInfo, error) {
phdrs := make([]elf.ProgHeader, hdr.Phnum)
for i := range phdrs {
var prog64 elf.Prog64
binary.Unmarshal(phdrBuf[:prog64Size], byteOrder, &prog64)
var prog64 linux.ElfProg64
prog64.UnmarshalUnsafe(phdrBuf[:prog64Size])
phdrBuf = phdrBuf[prog64Size:]
phdrs[i] = elf.ProgHeader{
Type: elf.ProgType(prog64.Type),
-1
View File
@@ -7,7 +7,6 @@ go_library(
srcs = ["statefile.go"],
visibility = ["//:sandbox"],
deps = [
"//pkg/binary",
"//pkg/compressio",
"//pkg/state/wire",
],
+18 -3
View File
@@ -48,6 +48,7 @@ import (
"compress/flate"
"crypto/hmac"
"crypto/sha256"
"encoding/binary"
"encoding/json"
"fmt"
"hash"
@@ -55,7 +56,6 @@ import (
"strings"
"time"
"gvisor.dev/gvisor/pkg/binary"
"gvisor.dev/gvisor/pkg/compressio"
"gvisor.dev/gvisor/pkg/state/wire"
)
@@ -90,6 +90,13 @@ type WriteCloser interface {
io.Closer
}
func writeMetadataLen(w io.Writer, val uint64) error {
var buf [8]byte
binary.BigEndian.PutUint64(buf[:], val)
_, err := w.Write(buf[:])
return err
}
// NewWriter returns a state data writer for a statefile.
//
// Note that the returned WriteCloser must be closed.
@@ -127,7 +134,7 @@ func NewWriter(w io.Writer, key []byte, metadata map[string]string) (WriteCloser
}
// Metadata length.
if err := binary.WriteUint64(mw, binary.BigEndian, uint64(len(b))); err != nil {
if err := writeMetadataLen(mw, uint64(len(b))); err != nil {
return nil, err
}
// Metadata bytes; io.MultiWriter will return a short write error if
@@ -158,6 +165,14 @@ func MetadataUnsafe(r io.Reader) (map[string]string, error) {
return metadata(r, nil)
}
func readMetadataLen(r io.Reader) (uint64, error) {
var buf [8]byte
if _, err := io.ReadFull(r, buf[:]); err != nil {
return 0, err
}
return binary.BigEndian.Uint64(buf[:]), nil
}
// metadata validates the magic header and reads out the metadata from a state
// data stream.
func metadata(r io.Reader, h hash.Hash) (map[string]string, error) {
@@ -183,7 +198,7 @@ func metadata(r io.Reader, h hash.Hash) (map[string]string, error) {
}
}()
metadataLen, err := binary.ReadUint64(r, binary.BigEndian)
metadataLen, err := readMetadataLen(r)
if err != nil {
return nil, err
}
+3 -1
View File
@@ -28,8 +28,10 @@ go_test(
srcs = ["seccomp_test.go"],
library = ":seccomp",
deps = [
"//pkg/binary",
"//pkg/abi/linux",
"//pkg/bpf",
"//pkg/hostarch",
"//pkg/marshal",
"@com_github_opencontainers_runtime_spec//specs-go:go_default_library",
"@org_golang_x_sys//unix:go_default_library",
],
+12 -17
View File
@@ -20,20 +20,15 @@ import (
specs "github.com/opencontainers/runtime-spec/specs-go"
"golang.org/x/sys/unix"
"gvisor.dev/gvisor/pkg/binary"
"gvisor.dev/gvisor/pkg/abi/linux"
"gvisor.dev/gvisor/pkg/bpf"
"gvisor.dev/gvisor/pkg/hostarch"
"gvisor.dev/gvisor/pkg/marshal"
)
type seccompData struct {
nr uint32
arch uint32
instructionPointer uint64
args [6]uint64
}
// asInput converts a seccompData to a bpf.Input.
func asInput(d seccompData) bpf.Input {
return bpf.InputBytes{binary.Marshal(nil, binary.LittleEndian, d), binary.LittleEndian}
// asInput converts a linux.SeccompData to a bpf.Input.
func asInput(d *linux.SeccompData) bpf.Input {
return bpf.InputBytes{marshal.Marshal(d), hostarch.ByteOrder}
}
// testInput creates an Input struct with given seccomp input values.
@@ -49,13 +44,13 @@ func testInput(arch uint32, syscallName string, args *[6]uint64) bpf.Input {
args = &argArray
}
data := seccompData{
nr: syscallNo,
arch: arch,
args: *args,
data := linux.SeccompData{
Nr: int32(syscallNo),
Arch: arch,
Args: *args,
}
return asInput(data)
return asInput(&data)
}
// testCase holds a seccomp test case.
@@ -100,7 +95,7 @@ var (
},
// Syscall matches but the arch is AUDIT_ARCH_X86 so the return
// value is the bad arch action.
input: asInput(seccompData{nr: 183, arch: 0x40000003}), //
input: asInput(&linux.SeccompData{Nr: 183, Arch: 0x40000003}), //
expected: uint32(killThreadAction),
},
{