mirror of
https://github.com/netbirdio/gvisor.git
synced 2026-05-22 17:12:49 -07:00
Improve loader related error messages returned to users.
PiperOrigin-RevId: 228382827 Change-Id: Ica1d30e0df826bdd77f180a5092b2b735ea5c804
This commit is contained in:
@@ -184,6 +184,7 @@ go_library(
|
||||
"//pkg/state",
|
||||
"//pkg/state/statefile",
|
||||
"//pkg/sync",
|
||||
"//pkg/syserr",
|
||||
"//pkg/syserror",
|
||||
"//pkg/tcpip",
|
||||
"//pkg/tcpip/stack",
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -44,6 +44,7 @@ go_library(
|
||||
"//pkg/sentry/uniqueid",
|
||||
"//pkg/sentry/usage",
|
||||
"//pkg/sentry/usermem",
|
||||
"//pkg/syserr",
|
||||
"//pkg/syserror",
|
||||
"//pkg/waiter",
|
||||
],
|
||||
|
||||
+11
-17
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user