diff options
-rw-r--r-- | pkg/sentry/kernel/BUILD | 1 | ||||
-rw-r--r-- | pkg/sentry/kernel/kernel.go | 7 | ||||
-rw-r--r-- | pkg/sentry/kernel/task_context.go | 13 | ||||
-rw-r--r-- | pkg/sentry/loader/BUILD | 1 | ||||
-rw-r--r-- | pkg/sentry/loader/loader.go | 28 | ||||
-rw-r--r-- | pkg/sentry/syscalls/linux/sys_thread.go | 6 |
6 files changed, 27 insertions, 29 deletions
diff --git a/pkg/sentry/kernel/BUILD b/pkg/sentry/kernel/BUILD index 490f674c0..7d41626dc 100644 --- a/pkg/sentry/kernel/BUILD +++ b/pkg/sentry/kernel/BUILD @@ -184,6 +184,7 @@ go_library( "//pkg/state", "//pkg/state/statefile", "//pkg/sync", + "//pkg/syserr", "//pkg/syserror", "//pkg/tcpip", "//pkg/tcpip/stack", diff --git a/pkg/sentry/kernel/kernel.go b/pkg/sentry/kernel/kernel.go index cb61e27f1..43e9823cb 100644 --- a/pkg/sentry/kernel/kernel.go +++ b/pkg/sentry/kernel/kernel.go @@ -31,6 +31,7 @@ package kernel import ( + "errors" "fmt" "io" "path/filepath" @@ -658,9 +659,9 @@ func (k *Kernel) CreateProcess(args CreateProcessArgs) (*ThreadGroup, ThreadID, // Create a fresh task context. remainingTraversals = uint(args.MaxSymlinkTraversals) - tc, err := k.LoadTaskImage(ctx, k.mounts, root, wd, &remainingTraversals, args.Filename, args.Argv, args.Envv, k.featureSet) - if err != nil { - return nil, 0, err + tc, se := k.LoadTaskImage(ctx, k.mounts, root, wd, &remainingTraversals, args.Filename, args.Argv, args.Envv, k.featureSet) + if se != nil { + return nil, 0, errors.New(se.String()) } // Take a reference on the FDMap, which will be transferred to diff --git a/pkg/sentry/kernel/task_context.go b/pkg/sentry/kernel/task_context.go index aaff309f0..ee3e49d17 100644 --- a/pkg/sentry/kernel/task_context.go +++ b/pkg/sentry/kernel/task_context.go @@ -15,9 +15,9 @@ package kernel import ( - "errors" "fmt" + "gvisor.googlesource.com/gvisor/pkg/abi/linux" "gvisor.googlesource.com/gvisor/pkg/cpuid" "gvisor.googlesource.com/gvisor/pkg/sentry/arch" "gvisor.googlesource.com/gvisor/pkg/sentry/context" @@ -26,10 +26,10 @@ import ( "gvisor.googlesource.com/gvisor/pkg/sentry/loader" "gvisor.googlesource.com/gvisor/pkg/sentry/mm" "gvisor.googlesource.com/gvisor/pkg/sentry/usermem" + "gvisor.googlesource.com/gvisor/pkg/syserr" ) -// ErrNoSyscalls is returned if there is no syscall table. -var ErrNoSyscalls = errors.New("no syscall table found") +var errNoSyscalls = syserr.New("no syscall table found", linux.ENOEXEC) // Auxmap contains miscellaneous data for the task. type Auxmap map[string]interface{} @@ -142,7 +142,7 @@ func (t *Task) Stack() *arch.Stack { // * argv: Binary argv // * envv: Binary envv // * fs: Binary FeatureSet -func (k *Kernel) LoadTaskImage(ctx context.Context, mounts *fs.MountNamespace, root, wd *fs.Dirent, maxTraversals *uint, filename string, argv, envv []string, fs *cpuid.FeatureSet) (*TaskContext, error) { +func (k *Kernel) LoadTaskImage(ctx context.Context, mounts *fs.MountNamespace, root, wd *fs.Dirent, maxTraversals *uint, filename string, argv, envv []string, fs *cpuid.FeatureSet) (*TaskContext, *syserr.Error) { // Prepare a new user address space to load into. m := mm.NewMemoryManager(k) defer m.DecUsers(ctx) @@ -155,8 +155,9 @@ func (k *Kernel) LoadTaskImage(ctx context.Context, mounts *fs.MountNamespace, r // Lookup our new syscall table. st, ok := LookupSyscallTable(os, ac.Arch()) if !ok { - // No syscall table found. Yikes. - return nil, ErrNoSyscalls + // No syscall table found. This means that the ELF binary does not match + // the architecture. + return nil, errNoSyscalls } if !m.IncUsers() { diff --git a/pkg/sentry/loader/BUILD b/pkg/sentry/loader/BUILD index 83cad186a..24e734b49 100644 --- a/pkg/sentry/loader/BUILD +++ b/pkg/sentry/loader/BUILD @@ -44,6 +44,7 @@ go_library( "//pkg/sentry/uniqueid", "//pkg/sentry/usage", "//pkg/sentry/usermem", + "//pkg/syserr", "//pkg/syserror", "//pkg/waiter", ], diff --git a/pkg/sentry/loader/loader.go b/pkg/sentry/loader/loader.go index e955502e3..deb8892f6 100644 --- a/pkg/sentry/loader/loader.go +++ b/pkg/sentry/loader/loader.go @@ -17,6 +17,7 @@ package loader import ( "bytes" + "fmt" "io" "path" @@ -30,6 +31,7 @@ import ( "gvisor.googlesource.com/gvisor/pkg/sentry/kernel/auth" "gvisor.googlesource.com/gvisor/pkg/sentry/mm" "gvisor.googlesource.com/gvisor/pkg/sentry/usermem" + "gvisor.googlesource.com/gvisor/pkg/syserr" "gvisor.googlesource.com/gvisor/pkg/syserror" ) @@ -196,20 +198,18 @@ func loadPath(ctx context.Context, m *mm.MemoryManager, mounts *fs.MountNamespac // Preconditions: // * The Task MemoryManager is empty. // * Load is called on the Task goroutine. -func Load(ctx context.Context, m *mm.MemoryManager, mounts *fs.MountNamespace, root, wd *fs.Dirent, maxTraversals *uint, fs *cpuid.FeatureSet, filename string, argv, envv []string, extraAuxv []arch.AuxEntry, vdso *VDSO) (abi.OS, arch.Context, string, error) { +func Load(ctx context.Context, m *mm.MemoryManager, mounts *fs.MountNamespace, root, wd *fs.Dirent, maxTraversals *uint, fs *cpuid.FeatureSet, filename string, argv, envv []string, extraAuxv []arch.AuxEntry, vdso *VDSO) (abi.OS, arch.Context, string, *syserr.Error) { // Load the binary itself. loaded, ac, d, argv, err := loadPath(ctx, m, mounts, root, wd, maxTraversals, fs, filename, argv) if err != nil { - ctx.Infof("Failed to load %s: %v", filename, err) - return 0, nil, "", err + return 0, nil, "", syserr.NewDynamic(fmt.Sprintf("Failed to load %s: %v", filename, err), syserr.FromError(err).ToLinux()) } defer d.DecRef() // Load the VDSO. vdsoAddr, err := loadVDSO(ctx, m, vdso, loaded) if err != nil { - ctx.Infof("Error loading VDSO: %v", err) - return 0, nil, "", err + return 0, nil, "", syserr.NewDynamic(fmt.Sprintf("Error loading VDSO: %v", err), syserr.FromError(err).ToLinux()) } // Setup the heap. brk starts at the next page after the end of the @@ -217,35 +217,30 @@ func Load(ctx context.Context, m *mm.MemoryManager, mounts *fs.MountNamespace, r // loaded.end is available for its use. e, ok := loaded.end.RoundUp() if !ok { - ctx.Warningf("brk overflows: %#x", loaded.end) - return 0, nil, "", syserror.ENOEXEC + return 0, nil, "", syserr.NewDynamic(fmt.Sprintf("brk overflows: %#x", loaded.end), linux.ENOEXEC) } m.BrkSetup(ctx, e) // Allocate our stack. stack, err := allocStack(ctx, m, ac) if err != nil { - ctx.Infof("Failed to allocate stack: %v", err) - return 0, nil, "", err + return 0, nil, "", syserr.NewDynamic(fmt.Sprintf("Failed to allocate stack: %v", err), syserr.FromError(err).ToLinux()) } // Push the original filename to the stack, for AT_EXECFN. execfn, err := stack.Push(filename) if err != nil { - ctx.Infof("Failed to push exec filename: %v", err) - return 0, nil, "", err + return 0, nil, "", syserr.NewDynamic(fmt.Sprintf("Failed to push exec filename: %v", err), syserr.FromError(err).ToLinux()) } // Push 16 random bytes on the stack which AT_RANDOM will point to. var b [16]byte if _, err := rand.Read(b[:]); err != nil { - ctx.Infof("Failed to read random bytes: %v", err) - return 0, nil, "", err + return 0, nil, "", syserr.NewDynamic(fmt.Sprintf("Failed to read random bytes: %v", err), syserr.FromError(err).ToLinux()) } random, err := stack.Push(b) if err != nil { - ctx.Infof("Failed to push random bytes: %v", err) - return 0, nil, "", err + return 0, nil, "", syserr.NewDynamic(fmt.Sprintf("Failed to push random bytes: %v", err), syserr.FromError(err).ToLinux()) } c := auth.CredentialsFromContext(ctx) @@ -266,8 +261,7 @@ func Load(ctx context.Context, m *mm.MemoryManager, mounts *fs.MountNamespace, r sl, err := stack.Load(argv, envv, auxv) if err != nil { - ctx.Infof("Failed to load stack: %v", err) - return 0, nil, "", err + return 0, nil, "", syserr.NewDynamic(fmt.Sprintf("Failed to load stack: %v", err), syserr.FromError(err).ToLinux()) } m.SetArgvStart(sl.ArgvStart) diff --git a/pkg/sentry/syscalls/linux/sys_thread.go b/pkg/sentry/syscalls/linux/sys_thread.go index c12693ee2..61cafefb9 100644 --- a/pkg/sentry/syscalls/linux/sys_thread.go +++ b/pkg/sentry/syscalls/linux/sys_thread.go @@ -104,9 +104,9 @@ func Execve(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.Syscal // Load the new TaskContext. maxTraversals := uint(linux.MaxSymlinkTraversals) - tc, err := t.Kernel().LoadTaskImage(t, t.MountNamespace(), root, wd, &maxTraversals, filename, argv, envv, t.Arch().FeatureSet()) - if err != nil { - return 0, nil, err + tc, se := t.Kernel().LoadTaskImage(t, t.MountNamespace(), root, wd, &maxTraversals, filename, argv, envv, t.Arch().FeatureSet()) + if se != nil { + return 0, nil, se.ToError() } ctrl, err := t.Execve(tc) |