diff options
Diffstat (limited to 'pkg/usermem')
-rw-r--r-- | pkg/usermem/BUILD | 5 | ||||
-rw-r--r-- | pkg/usermem/bytes_io.go | 10 | ||||
-rw-r--r-- | pkg/usermem/marshal.go | 43 | ||||
-rw-r--r-- | pkg/usermem/usermem.go | 19 | ||||
-rw-r--r-- | pkg/usermem/usermem_test.go | 20 |
5 files changed, 70 insertions, 27 deletions
diff --git a/pkg/usermem/BUILD b/pkg/usermem/BUILD index 3dba36f12..9c37a9626 100644 --- a/pkg/usermem/BUILD +++ b/pkg/usermem/BUILD @@ -7,16 +7,17 @@ go_library( srcs = [ "bytes_io.go", "bytes_io_unsafe.go", + "marshal.go", "usermem.go", ], visibility = ["//:sandbox"], deps = [ "//pkg/atomicbitops", "//pkg/context", + "//pkg/errors/linuxerr", "//pkg/gohacks", "//pkg/hostarch", "//pkg/safemem", - "//pkg/syserror", ], ) @@ -29,8 +30,8 @@ go_test( library = ":usermem", deps = [ "//pkg/context", + "//pkg/errors/linuxerr", "//pkg/hostarch", "//pkg/safemem", - "//pkg/syserror", ], ) diff --git a/pkg/usermem/bytes_io.go b/pkg/usermem/bytes_io.go index 3da3c0294..777ac59a6 100644 --- a/pkg/usermem/bytes_io.go +++ b/pkg/usermem/bytes_io.go @@ -16,9 +16,9 @@ package usermem import ( "gvisor.dev/gvisor/pkg/context" + "gvisor.dev/gvisor/pkg/errors/linuxerr" "gvisor.dev/gvisor/pkg/hostarch" "gvisor.dev/gvisor/pkg/safemem" - "gvisor.dev/gvisor/pkg/syserror" ) const maxInt = int(^uint(0) >> 1) @@ -51,7 +51,7 @@ func (b *BytesIO) CopyIn(ctx context.Context, addr hostarch.Addr, dst []byte, op // ZeroOut implements IO.ZeroOut. func (b *BytesIO) ZeroOut(ctx context.Context, addr hostarch.Addr, toZero int64, opts IOOpts) (int64, error) { if toZero > int64(maxInt) { - return 0, syserror.EINVAL + return 0, linuxerr.EINVAL } rngN, rngErr := b.rangeCheck(addr, int(toZero)) if rngN == 0 { @@ -89,15 +89,15 @@ func (b *BytesIO) rangeCheck(addr hostarch.Addr, length int) (int, error) { return 0, nil } if length < 0 { - return 0, syserror.EINVAL + return 0, linuxerr.EINVAL } max := hostarch.Addr(len(b.Bytes)) if addr >= max { - return 0, syserror.EFAULT + return 0, linuxerr.EFAULT } end, ok := addr.AddLength(uint64(length)) if !ok || end > max { - return int(max - addr), syserror.EFAULT + return int(max - addr), linuxerr.EFAULT } return length, nil } diff --git a/pkg/usermem/marshal.go b/pkg/usermem/marshal.go new file mode 100644 index 000000000..5b5a662dc --- /dev/null +++ b/pkg/usermem/marshal.go @@ -0,0 +1,43 @@ +// Copyright 2021 The gVisor Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package usermem + +import ( + "gvisor.dev/gvisor/pkg/context" + "gvisor.dev/gvisor/pkg/hostarch" +) + +// IOCopyContext wraps an object implementing hostarch.IO to implement +// marshal.CopyContext. +type IOCopyContext struct { + Ctx context.Context + IO IO + Opts IOOpts +} + +// CopyScratchBuffer implements marshal.CopyContext.CopyScratchBuffer. +func (i *IOCopyContext) CopyScratchBuffer(size int) []byte { + return make([]byte, size) +} + +// CopyOutBytes implements marshal.CopyContext.CopyOutBytes. +func (i *IOCopyContext) CopyOutBytes(addr hostarch.Addr, b []byte) (int, error) { + return i.IO.CopyOut(i.Ctx, addr, b, i.Opts) +} + +// CopyInBytes implements marshal.CopyContext.CopyInBytes. +func (i *IOCopyContext) CopyInBytes(addr hostarch.Addr, b []byte) (int, error) { + return i.IO.CopyIn(i.Ctx, addr, b, i.Opts) +} diff --git a/pkg/usermem/usermem.go b/pkg/usermem/usermem.go index 0d6d25e50..f46a00e42 100644 --- a/pkg/usermem/usermem.go +++ b/pkg/usermem/usermem.go @@ -22,11 +22,10 @@ import ( "strconv" "gvisor.dev/gvisor/pkg/context" + "gvisor.dev/gvisor/pkg/errors/linuxerr" "gvisor.dev/gvisor/pkg/gohacks" - "gvisor.dev/gvisor/pkg/safemem" - "gvisor.dev/gvisor/pkg/syserror" - "gvisor.dev/gvisor/pkg/hostarch" + "gvisor.dev/gvisor/pkg/safemem" ) // IO provides access to the contents of a virtual memory space. @@ -163,7 +162,7 @@ func (rw *IOReadWriter) Read(dst []byte) (int, error) { // Disallow wraparound. rw.Addr = ^hostarch.Addr(0) if err != nil { - err = syserror.EFAULT + err = linuxerr.EFAULT } } return n, err @@ -179,7 +178,7 @@ func (rw *IOReadWriter) Write(src []byte) (int, error) { // Disallow wraparound. rw.Addr = ^hostarch.Addr(0) if err != nil { - err = syserror.EFAULT + err = linuxerr.EFAULT } } return n, err @@ -214,7 +213,7 @@ func CopyStringIn(ctx context.Context, uio IO, addr hostarch.Addr, maxlen int, o } end, ok := addr.AddLength(uint64(readlen)) if !ok { - return gohacks.StringFromImmutableBytes(buf[:done]), syserror.EFAULT + return gohacks.StringFromImmutableBytes(buf[:done]), linuxerr.EFAULT } // Shorten the read to avoid crossing page boundaries, since faulting // in a page unnecessarily is expensive. This also ensures that partial @@ -244,7 +243,7 @@ func CopyStringIn(ctx context.Context, uio IO, addr hostarch.Addr, maxlen int, o } addr = end } - return gohacks.StringFromImmutableBytes(buf), syserror.ENAMETOOLONG + return gohacks.StringFromImmutableBytes(buf), linuxerr.ENAMETOOLONG } // CopyOutVec copies bytes from src to the memory mapped at ars in uio. The @@ -382,7 +381,7 @@ func CopyInt32StringsInVec(ctx context.Context, uio IO, ars hostarch.AddrRangeSe // Parse a single value. val, err := strconv.ParseInt(string(buf[i:nextI]), 10, 32) if err != nil { - return int64(i), syserror.EINVAL + return int64(i), linuxerr.EINVAL } dsts[j] = int32(val) @@ -398,7 +397,7 @@ func CopyInt32StringsInVec(ctx context.Context, uio IO, ars hostarch.AddrRangeSe return int64(i), cperr } if j == 0 { - return int64(i), syserror.EINVAL + return int64(i), linuxerr.EINVAL } return int64(i), nil } @@ -430,7 +429,7 @@ type IOSequence struct { // return 0, nil // } // if f.availableBytes == 0 { -// return 0, syserror.ErrWouldBlock +// return 0, linuxerr.ErrWouldBlock // } // return ioseq.CopyOutFrom(..., reader) // diff --git a/pkg/usermem/usermem_test.go b/pkg/usermem/usermem_test.go index 9b697b593..a5e2fe69e 100644 --- a/pkg/usermem/usermem_test.go +++ b/pkg/usermem/usermem_test.go @@ -22,9 +22,9 @@ import ( "testing" "gvisor.dev/gvisor/pkg/context" + "gvisor.dev/gvisor/pkg/errors/linuxerr" "gvisor.dev/gvisor/pkg/hostarch" "gvisor.dev/gvisor/pkg/safemem" - "gvisor.dev/gvisor/pkg/syserror" ) // newContext returns a context.Context that we can use in these tests (we @@ -51,7 +51,7 @@ func TestBytesIOCopyOutSuccess(t *testing.T) { func TestBytesIOCopyOutFailure(t *testing.T) { b := newBytesIOString("ABC") n, err := b.CopyOut(newContext(), 1, []byte("foo"), IOOpts{}) - if wantN, wantErr := 2, syserror.EFAULT; n != wantN || err != wantErr { + if wantN, wantErr := 2, linuxerr.EFAULT; n != wantN || err != wantErr { t.Errorf("CopyOut: got (%v, %v), wanted (%v, %v)", n, err, wantN, wantErr) } if got, want := b.Bytes, []byte("Afo"); !bytes.Equal(got, want) { @@ -75,7 +75,7 @@ func TestBytesIOCopyInFailure(t *testing.T) { b := newBytesIOString("Afo") var dst [3]byte n, err := b.CopyIn(newContext(), 1, dst[:], IOOpts{}) - if wantN, wantErr := 2, syserror.EFAULT; n != wantN || err != wantErr { + if wantN, wantErr := 2, linuxerr.EFAULT; n != wantN || err != wantErr { t.Errorf("CopyIn: got (%v, %v), wanted (%v, %v)", n, err, wantN, wantErr) } if got, want := dst[:], []byte("fo\x00"); !bytes.Equal(got, want) { @@ -97,7 +97,7 @@ func TestBytesIOZeroOutSuccess(t *testing.T) { func TestBytesIOZeroOutFailure(t *testing.T) { b := newBytesIOString("ABC") n, err := b.ZeroOut(newContext(), 1, 3, IOOpts{}) - if wantN, wantErr := int64(2), syserror.EFAULT; n != wantN || err != wantErr { + if wantN, wantErr := int64(2), linuxerr.EFAULT; n != wantN || err != wantErr { t.Errorf("ZeroOut: got (%v, %v), wanted (%v, %v)", n, err, wantN, wantErr) } if got, want := b.Bytes, []byte("A\x00\x00"); !bytes.Equal(got, want) { @@ -125,7 +125,7 @@ func TestBytesIOCopyOutFromFailure(t *testing.T) { {Start: 1, End: 4}, {Start: 4, End: 7}, }), safemem.FromIOReader{bytes.NewBufferString("foobar")}, IOOpts{}) - if wantN, wantErr := int64(4), syserror.EFAULT; n != wantN || err != wantErr { + if wantN, wantErr := int64(4), linuxerr.EFAULT; n != wantN || err != wantErr { t.Errorf("CopyOutFrom: got (%v, %v), wanted (%v, %v)", n, err, wantN, wantErr) } if got, want := b.Bytes, []byte("Afoob"); !bytes.Equal(got, want) { @@ -155,7 +155,7 @@ func TestBytesIOCopyInToFailure(t *testing.T) { {Start: 1, End: 4}, {Start: 4, End: 7}, }), safemem.FromIOWriter{&dst}, IOOpts{}) - if wantN, wantErr := int64(4), syserror.EFAULT; n != wantN || err != wantErr { + if wantN, wantErr := int64(4), linuxerr.EFAULT; n != wantN || err != wantErr { t.Errorf("CopyOutFrom: got (%v, %v), wanted (%v, %v)", n, err, wantN, wantErr) } if got, want := dst.Bytes(), []byte("foob"); !bytes.Equal(got, want) { @@ -206,14 +206,14 @@ func TestCopyStringInVeryLong(t *testing.T) { func TestCopyStringInNoTerminatingZeroByte(t *testing.T) { want := strings.Repeat("A", copyStringIncrement-1) got, err := CopyStringIn(newContext(), newBytesIOString(want), 0, 2*copyStringIncrement, IOOpts{}) - if wantErr := syserror.EFAULT; got != want || err != wantErr { + if wantErr := linuxerr.EFAULT; got != want || err != wantErr { t.Errorf("CopyStringIn: got (%q, %v), wanted (%q, %v)", got, err, want, wantErr) } } func TestCopyStringInTruncatedByMaxlen(t *testing.T) { got, err := CopyStringIn(newContext(), newBytesIOString(strings.Repeat("A", 10)), 0, 5, IOOpts{}) - if want, wantErr := strings.Repeat("A", 5), syserror.ENAMETOOLONG; got != want || err != wantErr { + if want, wantErr := strings.Repeat("A", 5), linuxerr.ENAMETOOLONG; got != want || err != wantErr { t.Errorf("CopyStringIn: got (%q, %v), wanted (%q, %v)", got, err, want, wantErr) } } @@ -272,8 +272,8 @@ func TestCopyInt32StringsInVecRequiresOneValidValue(t *testing.T) { src := BytesIOSequence([]byte(s)) initial := []int32{1, 2} dsts := append([]int32(nil), initial...) - if n, err := CopyInt32StringsInVec(newContext(), src.IO, src.Addrs, dsts, src.Opts); err != syserror.EINVAL { - t.Errorf("CopyInt32StringsInVec: got (%d, %v), wanted (_, %v)", n, err, syserror.EINVAL) + if n, err := CopyInt32StringsInVec(newContext(), src.IO, src.Addrs, dsts, src.Opts); !linuxerr.Equals(linuxerr.EINVAL, err) { + t.Errorf("CopyInt32StringsInVec: got (%d, %v), wanted (_, %v)", n, err, linuxerr.EINVAL) } if !reflect.DeepEqual(dsts, initial) { t.Errorf("dsts: got %v, wanted %v", dsts, initial) |