Skip to content

Commit 5712655

Browse files
authored
Merge pull request #688 from kzys/fix-join
prepareBindMounts must not modify files outside of the jail
2 parents d7eeea7 + 95c43cd commit 5712655

File tree

2 files changed

+60
-1
lines changed

2 files changed

+60
-1
lines changed

runtime/runc_jailer.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import (
2525
"syscall"
2626
"time"
2727

28+
"github.com/containerd/continuity/fs"
2829
"github.com/containerd/go-runc"
2930
"github.com/hashicorp/go-multierror"
3031
"github.com/opencontainers/runtime-spec/specs-go"
@@ -144,7 +145,11 @@ func (j *runcJailer) prepareBindMounts(mounts []*proto.FirecrackerDriveMount) er
144145
// Only bindMount regular file.
145146
// To avoid duplicate files, for block device, we will use system call to create device file for it.
146147
if stat.Mode&syscall.S_IFMT == syscall.S_IFREG {
147-
err := j.bindMountFileToJail(m.HostPath, filepath.Join(j.RootPath(), m.HostPath))
148+
dest, err := fs.RootPath(j.RootPath(), m.HostPath)
149+
if err != nil {
150+
return err
151+
}
152+
err = j.bindMountFileToJail(m.HostPath, dest)
148153
if err != nil {
149154
return err
150155
}

runtime/runc_jailer_test.go

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,3 +223,57 @@ func TestFifoHandler(t *testing.T) {
223223
})
224224
}
225225
}
226+
227+
func TestPrepareBindMount(t *testing.T) {
228+
// Because of chown(2).
229+
internal.RequiresRoot(t)
230+
231+
t.Run("no mounts", func(t *testing.T) {
232+
j := &runcJailer{}
233+
err := j.prepareBindMounts([]*proto.FirecrackerDriveMount{})
234+
require.NoError(t, err)
235+
})
236+
237+
dir, err := ioutil.TempDir("", t.Name())
238+
require.NoError(t, err)
239+
defer os.RemoveAll(dir)
240+
241+
j := &runcJailer{Config: runcJailerConfig{
242+
OCIBundlePath: filepath.Join(dir, "bundle"),
243+
UID: 1234,
244+
GID: 5678,
245+
}}
246+
247+
err = ioutil.WriteFile(dir+"/foobar", []byte("hello"), 0700)
248+
require.NoError(t, err)
249+
250+
testcases := []struct {
251+
name string
252+
hostPath string
253+
}{
254+
{
255+
name: "absolute path",
256+
hostPath: dir + "/foobar",
257+
},
258+
{
259+
name: "use dots to access the original directory",
260+
hostPath: "/../../../../../.." + dir + "/foobar",
261+
},
262+
}
263+
for _, tc := range testcases {
264+
t.Run(tc.name, func(t *testing.T) {
265+
err = j.prepareBindMounts([]*proto.FirecrackerDriveMount{{
266+
HostPath: tc.hostPath,
267+
FilesystemType: "ext4",
268+
VMPath: "/mnt",
269+
}})
270+
require.NoError(t, err)
271+
stat, err := os.Stat(dir)
272+
require.NoError(t, err)
273+
274+
s := stat.Sys().(*syscall.Stat_t)
275+
assert.Equal(t, 0, int(s.Uid), "UID")
276+
assert.Equal(t, 0, int(s.Gid), "GID")
277+
})
278+
}
279+
}

0 commit comments

Comments
 (0)