summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--pkg/sentry/syscalls/linux/error.go26
-rw-r--r--pkg/syserror/syserror.go10
2 files changed, 21 insertions, 15 deletions
diff --git a/pkg/sentry/syscalls/linux/error.go b/pkg/sentry/syscalls/linux/error.go
index 5bd526b73..efec93f73 100644
--- a/pkg/sentry/syscalls/linux/error.go
+++ b/pkg/sentry/syscalls/linux/error.go
@@ -75,17 +75,25 @@ func handleIOError(ctx context.Context, partialResult bool, ioerr, intr error, o
// errors, we may consume the error and return only the partial read/write.
//
// Returns false if error is unknown.
-func handleIOErrorImpl(ctx context.Context, partialResult bool, err, intr error, op string) (bool, error) {
- switch err {
- case nil:
+func handleIOErrorImpl(ctx context.Context, partialResult bool, errOrig, intr error, op string) (bool, error) {
+ if errOrig == nil {
// Typical successful syscall.
return true, nil
+ }
+
+ // Translate error, if possible, to consolidate errors from other packages
+ // into a smaller set of errors from syserror package.
+ translatedErr := errOrig
+ if errno, ok := syserror.TranslateError(errOrig); ok {
+ translatedErr = errno
+ }
+ switch translatedErr {
case io.EOF:
// EOF is always consumed. If this is a partial read/write
// (result != 0), the application will see that, otherwise
// they will see 0.
return true, nil
- case syserror.ErrExceedsFileSizeLimit:
+ case syserror.EFBIG:
t := kernel.TaskFromContext(ctx)
if t == nil {
panic("I/O error should only occur from a context associated with a Task")
@@ -98,7 +106,7 @@ func handleIOErrorImpl(ctx context.Context, partialResult bool, err, intr error,
// Simultaneously send a SIGXFSZ per setrlimit(2).
t.SendSignal(kernel.SignalInfoNoInfo(linux.SIGXFSZ, t, t))
return true, syserror.EFBIG
- case syserror.ErrInterrupted:
+ case syserror.EINTR:
// The syscall was interrupted. Return nil if it completed
// partially, otherwise return the error code that the syscall
// needs (to indicate to the kernel what it should do).
@@ -110,10 +118,10 @@ func handleIOErrorImpl(ctx context.Context, partialResult bool, err, intr error,
if !partialResult {
// Typical syscall error.
- return true, err
+ return true, errOrig
}
- switch err {
+ switch translatedErr {
case syserror.EINTR:
// Syscall interrupted, but completed a partial
// read/write. Like ErrWouldBlock, since we have a
@@ -143,7 +151,7 @@ func handleIOErrorImpl(ctx context.Context, partialResult bool, err, intr error,
// For TCP sendfile connections, we may have a reset or timeout. But we
// should just return n as the result.
return true, nil
- case syserror.ErrWouldBlock:
+ case syserror.EWOULDBLOCK:
// Syscall would block, but completed a partial read/write.
// This case should only be returned by IssueIO for nonblocking
// files. Since we have a partial read/write, we consume
@@ -151,7 +159,7 @@ func handleIOErrorImpl(ctx context.Context, partialResult bool, err, intr error,
return true, nil
}
- switch err.(type) {
+ switch errOrig.(type) {
case syserror.SyscallRestartErrno:
// Identical to the EINTR case.
return true, nil
diff --git a/pkg/syserror/syserror.go b/pkg/syserror/syserror.go
index 97de17afe..56b621357 100644
--- a/pkg/syserror/syserror.go
+++ b/pkg/syserror/syserror.go
@@ -130,17 +130,15 @@ func AddErrorUnwrapper(unwrap func(e error) (unix.Errno, bool)) {
// TranslateError translates errors to errnos, it will return false if
// the error was not registered.
func TranslateError(from error) (unix.Errno, bool) {
- err, ok := errorMap[from]
- if ok {
- return err, ok
+ if err, ok := errorMap[from]; ok {
+ return err, true
}
// Try to unwrap the error if we couldn't match an error
// exactly. This might mean that a package has its own
// error type.
for _, unwrap := range errorUnwrappers {
- err, ok := unwrap(from)
- if ok {
- return err, ok
+ if err, ok := unwrap(from); ok {
+ return err, true
}
}
return 0, false