Skip to content

Commit 666cb5e

Browse files
committed
Make runc_jailer's behavior configurable regarding drive files
runc_jailer implicitly copies all drive files to a jail directory before calling runc. While copying provides a stronger guarantee of isolation, some clients would want have more control on the drive files (e.g. use shred(1) for removing files). DriveExposePolicy allows client to use bind-mount instead of copying. Signed-off-by: Kazuyoshi Kato <[email protected]>
1 parent 9ba55b5 commit 666cb5e

File tree

5 files changed

+186
-68
lines changed

5 files changed

+186
-68
lines changed

proto/firecracker.pb.go

Lines changed: 86 additions & 44 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

proto/firecracker.proto

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,15 @@ message GetVMMetadataResponse {
8181
string Metadata = 1;
8282
}
8383

84+
// DriveExposePolicy is used to configure the method to expose drive files.
85+
// "COPY" is copying the files to the jail, which is the default behavior.
86+
// "BIND" is bind-mounting the files on the jail, assuming a caller pre-configures the permissions of
87+
// the files appropriately.
88+
enum DriveExposePolicy {
89+
COPY = 0;
90+
BIND = 1;
91+
}
92+
8493
message JailerConfig {
8594
string NetNS = 1;
8695
// List of the physical numbers of the CPUs on which processes in that
@@ -110,5 +119,8 @@ message JailerConfig {
110119
// if no value was provided, then /firecracker-containerd will be used as
111120
// the default value
112121
string CgroupPath = 6;
122+
123+
// DriveExposePolicy is used to configure the method to expose drive files.
124+
DriveExposePolicy DriveExposePolicy = 7;
113125
}
114126

runtime/jailer.go

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,13 @@ import (
1818
"fmt"
1919
"os"
2020

21-
"github.com/firecracker-microvm/firecracker-go-sdk"
2221
"github.com/pkg/errors"
2322
"github.com/sirupsen/logrus"
2423

2524
"github.com/firecracker-microvm/firecracker-containerd/config"
2625
"github.com/firecracker-microvm/firecracker-containerd/internal/vm"
2726
"github.com/firecracker-microvm/firecracker-containerd/proto"
27+
firecracker "github.com/firecracker-microvm/firecracker-go-sdk"
2828
)
2929

3030
const (
@@ -95,14 +95,15 @@ func newJailer(
9595

9696
l := logger.WithField("jailer", "runc")
9797
config := runcJailerConfig{
98-
OCIBundlePath: ociBundlePath,
99-
RuncBinPath: service.config.JailerConfig.RuncBinaryPath,
100-
RuncConfigPath: service.config.JailerConfig.RuncConfigPath,
101-
UID: request.JailerConfig.UID,
102-
GID: request.JailerConfig.GID,
103-
CPUs: request.JailerConfig.CPUs,
104-
Mems: request.JailerConfig.Mems,
105-
CgroupPath: request.JailerConfig.CgroupPath,
98+
OCIBundlePath: ociBundlePath,
99+
RuncBinPath: service.config.JailerConfig.RuncBinaryPath,
100+
RuncConfigPath: service.config.JailerConfig.RuncConfigPath,
101+
UID: request.JailerConfig.UID,
102+
GID: request.JailerConfig.GID,
103+
CPUs: request.JailerConfig.CPUs,
104+
Mems: request.JailerConfig.Mems,
105+
CgroupPath: request.JailerConfig.CgroupPath,
106+
DriveExposePolicy: request.JailerConfig.DriveExposePolicy,
106107
}
107108
return newRuncJailer(ctx, l, service.vmID, config)
108109
}

runtime/jailer_integ_test.go

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,10 @@ package main
1515

1616
import (
1717
"context"
18+
"io/ioutil"
1819
"os"
1920
"path/filepath"
21+
"strings"
2022
"testing"
2123

2224
"github.com/containerd/containerd"
@@ -44,6 +46,13 @@ func TestJailer_Isolated(t *testing.T) {
4446
GID: 300001,
4547
})
4648
})
49+
t.Run("With Jailer and bind-mount", func(t *testing.T) {
50+
testJailer(t, &proto.JailerConfig{
51+
UID: 300001,
52+
GID: 300001,
53+
DriveExposePolicy: proto.DriveExposePolicy_BIND,
54+
})
55+
})
4756
}
4857

4958
func testJailer(t *testing.T, jailerConfig *proto.JailerConfig) {
@@ -63,11 +72,30 @@ func testJailer(t *testing.T, jailerConfig *proto.JailerConfig) {
6372

6473
vmID := testNameToVMID(t.Name())
6574

66-
fcClient := fccontrol.NewFirecrackerClient(pluginClient.Client())
67-
_, err = fcClient.CreateVM(ctx, &proto.CreateVMRequest{
75+
request := proto.CreateVMRequest{
6876
VMID: vmID,
6977
JailerConfig: jailerConfig,
70-
})
78+
}
79+
80+
// If the drive files are bind-mounted, the files must be readable from the jailer's user.
81+
if jailerConfig != nil && jailerConfig.DriveExposePolicy == proto.DriveExposePolicy_BIND {
82+
f, err := ioutil.TempFile("", strings.Replace(t.Name(), "/", "-", -1))
83+
require.NoError(err)
84+
defer f.Close()
85+
86+
dst := f.Name()
87+
88+
err = copyFile(defaultRuntimeConfig.RootDrive, dst, 0400)
89+
require.NoErrorf(err, "failed to copy a rootfs as %q", dst)
90+
91+
err = os.Chown(dst, int(jailerConfig.UID), int(jailerConfig.GID))
92+
require.NoError(err, "failed to chown %q", dst)
93+
94+
request.RootDrive = &proto.FirecrackerRootDrive{HostPath: dst}
95+
}
96+
97+
fcClient := fccontrol.NewFirecrackerClient(pluginClient.Client())
98+
_, err = fcClient.CreateVM(ctx, &request)
7199
require.NoError(err)
72100

73101
c, err := client.NewContainer(ctx,

0 commit comments

Comments
 (0)