summaryrefslogtreecommitdiffhomepage
path: root/pkg/usermem
diff options
context:
space:
mode:
Diffstat (limited to 'pkg/usermem')
-rw-r--r--pkg/usermem/BUILD5
-rw-r--r--pkg/usermem/bytes_io.go10
-rw-r--r--pkg/usermem/marshal.go43
-rw-r--r--pkg/usermem/usermem.go19
-rw-r--r--pkg/usermem/usermem_test.go20
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)