Load loads args.File into a MemoryManager. If args.File is nil, the path args.Filename is resolved and loaded instead. Load also returns the new credentials for the task after execve and a bool indicating whether the task is executing with elevated privileges. If Load returns ErrSwitchFile it shoul
(ctx context.Context, args LoadArgs, extraAuxv []arch.AuxEntry, vdso *VDSO)
| 272 | // - The Task MemoryManager is empty. |
| 273 | // - Load is called on the Task goroutine. |
| 274 | func Load(ctx context.Context, args LoadArgs, extraAuxv []arch.AuxEntry, vdso *VDSO) (ImageInfo, *auth.Credentials, bool, *syserr.Error) { |
| 275 | // Load the executable itself. |
| 276 | loaded, ac, file, newArgv, err := loadExecutable(ctx, args) |
| 277 | if err != nil { |
| 278 | return ImageInfo{}, nil, false, syserr.NewDynamic(fmt.Sprintf("failed to load %s: %v", args.Filename, err), syserr.FromError(err).ToLinux()) |
| 279 | } |
| 280 | defer file.DecRef(ctx) |
| 281 | |
| 282 | // Load the VDSO. |
| 283 | vdsoAddr, err := loadVDSO(ctx, args.MemoryManager, vdso, loaded) |
| 284 | if err != nil { |
| 285 | return ImageInfo{}, nil, false, syserr.NewDynamic(fmt.Sprintf("error loading VDSO: %v", err), syserr.FromError(err).ToLinux()) |
| 286 | } |
| 287 | |
| 288 | // Setup the heap. brk starts at the next page after the end of the |
| 289 | // executable. Userspace can assume that the remainder of the page after |
| 290 | // loaded.end is available for its use. |
| 291 | e, ok := loaded.end.RoundUp() |
| 292 | if !ok { |
| 293 | return ImageInfo{}, nil, false, syserr.NewDynamic(fmt.Sprintf("brk overflows: %#x", loaded.end), errno.ENOEXEC) |
| 294 | } |
| 295 | args.MemoryManager.BrkSetup(ctx, e) |
| 296 | |
| 297 | // Allocate our stack. |
| 298 | stack, err := allocStack(ctx, args.MemoryManager, ac) |
| 299 | if err != nil { |
| 300 | return ImageInfo{}, nil, false, syserr.NewDynamic(fmt.Sprintf("Failed to allocate stack: %v", err), syserr.FromError(err).ToLinux()) |
| 301 | } |
| 302 | |
| 303 | // Push the original filename to the stack, for AT_EXECFN. |
| 304 | if _, err := stack.PushNullTerminatedByteSlice([]byte(args.Filename)); err != nil { |
| 305 | return ImageInfo{}, nil, false, syserr.NewDynamic(fmt.Sprintf("Failed to push exec filename: %v", err), syserr.FromError(err).ToLinux()) |
| 306 | } |
| 307 | execfn := stack.Bottom |
| 308 | |
| 309 | // Push 16 random bytes on the stack which AT_RANDOM will point to. |
| 310 | var b [16]byte |
| 311 | if _, err := rand.Read(b[:]); err != nil { |
| 312 | return ImageInfo{}, nil, false, syserr.NewDynamic(fmt.Sprintf("Failed to read random bytes: %v", err), syserr.FromError(err).ToLinux()) |
| 313 | } |
| 314 | if _, err = stack.PushNullTerminatedByteSlice(b[:]); err != nil { |
| 315 | return ImageInfo{}, nil, false, syserr.NewDynamic(fmt.Sprintf("Failed to push random bytes: %v", err), syserr.FromError(err).ToLinux()) |
| 316 | } |
| 317 | random := stack.Bottom |
| 318 | |
| 319 | filePrivs, err := file.GetFilePrivileges(ctx) |
| 320 | if err != nil { |
| 321 | return ImageInfo{}, nil, false, syserr.NewDynamic(fmt.Sprintf("failed to read file privileges of %s: %v", args.Filename, err), syserr.FromError(err).ToLinux()) |
| 322 | } |
| 323 | c, secureExec, err := auth.ComputeCredsForExec(auth.CredentialsFromContext(ctx), filePrivs, file.MappedName(ctx), |
| 324 | args.NoNewPrivs, args.StopPrivGain, args.AllowSUID) |
| 325 | if err != nil { |
| 326 | return ImageInfo{}, nil, false, syserr.NewDynamic(fmt.Sprintf("failed to update creds with file privileges: %v", err), syserr.FromError(err).ToLinux()) |
| 327 | } |
| 328 | secureExecInt := 0 |
| 329 | if secureExec { |
| 330 | secureExecInt = 1 |
| 331 | } |
no test coverage detected
searching dependent graphs…