-
Notifications
You must be signed in to change notification settings - Fork 193
/
Copy pathjailer.go
108 lines (94 loc) · 3.91 KB
/
jailer.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License"). You may
// not use this file except in compliance with the License. A copy of the
// License is located at
//
// http://aws.amazon.com/apache2.0/
//
// or in the "license" file accompanying this file. This file 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 main
import (
"context"
"fmt"
"os"
"github.com/sirupsen/logrus"
"github.com/firecracker-microvm/firecracker-containerd/config"
"github.com/firecracker-microvm/firecracker-containerd/internal/vm"
"github.com/firecracker-microvm/firecracker-containerd/proto"
firecracker "github.com/firecracker-microvm/firecracker-go-sdk"
)
const (
kernelImageFileName = "kernel-image"
jailerHandlerName = "firecracker-containerd-jail-handler"
jailerFifoHandlerName = "firecracker-containerd-jail-fifo-handler"
rootfsFolder = "rootfs"
)
// jailer will allow modification and provide options to the the Firecracker VM
// to allow for jailing. In addition, this will allow for given files to be exposed
// to the jailed filesystem.
type jailer interface {
// BuildJailedMachine will modify the firecracker.Config and provide
// firecracker.Opt to be passed into firecracker.NewMachine which will allow
// for the VM to be jailed.
BuildJailedMachine(cfg *config.Config, machineCfg *firecracker.Config, vmID string) ([]firecracker.Opt, error)
// ExposeFileToJail will expose the given file to the jailed filesystem, including
// regular files and block devices. An error is returned if provided a path to a file
// with type that is not supported.
ExposeFileToJail(path string) error
// JailPath is used to return the directory we are supposed to be working in.
JailPath() vm.Dir
// StubDrivesOptions will return a set of options used to create a new stub
// drive file
StubDrivesOptions() []FileOpt
// Stop the jailer as a way that is visible from the user-level process (e.g. SIGTERM).
Stop(force bool) error
// Close will do any necessary cleanup that the jailer has accrued.
Close() error
}
type cgroupPather interface {
CgroupPath() string
}
// FileOpt is a functional option that operates on an open file, modifying it to be usable
// by the jailer implementation providing the option.
type FileOpt func(*os.File) error
// newJailer is used to construct a jailer from the CreateVM request. If no
// request or jailer config was provided, then the noopJailer will be returned.
func newJailer(
ctx context.Context,
logger *logrus.Entry,
ociBundlePath string,
service *service,
request *proto.CreateVMRequest,
) (jailer, error) {
if request == nil || request.JailerConfig == nil {
l := logger.WithField("jailer", "noop")
return newNoopJailer(ctx, l, service.shimDir), nil
}
if request.JailerConfig.UID == 0 || request.JailerConfig.GID == 0 {
return nil, fmt.Errorf(
"attempting to run as %d:%d. 0 cannot be used for the UID or GID",
request.JailerConfig.UID,
request.JailerConfig.GID,
)
}
if err := os.MkdirAll(ociBundlePath, 0700); err != nil {
return nil, fmt.Errorf("failed to create oci bundle path: %s: %w", ociBundlePath, err)
}
l := logger.WithField("jailer", "runc")
config := runcJailerConfig{
OCIBundlePath: ociBundlePath,
RuncBinPath: service.config.JailerConfig.RuncBinaryPath,
RuncConfigPath: service.config.JailerConfig.RuncConfigPath,
UID: request.JailerConfig.UID,
GID: request.JailerConfig.GID,
CPUs: request.JailerConfig.CPUs,
Mems: request.JailerConfig.Mems,
CgroupPath: request.JailerConfig.CgroupPath,
DriveExposePolicy: request.JailerConfig.DriveExposePolicy,
}
return newRuncJailer(ctx, l, service.vmID, config, request.DriveMounts)
}