From a88af321f7c591404b0316320c46591fa8250992 Mon Sep 17 00:00:00 2001 From: Archana Shinde Date: Wed, 3 Jun 2020 08:27:36 -0700 Subject: [PATCH] device: Do not allow container access to the nvdimm rootfs With this change, a container is not longer given access to the underlying nvdimm root partition. This is done by explicitly adding the nvdimm root partition to the device cgroup of the container. Fixes #791 Signed-off-by: Archana Shinde --- device.go | 26 ++++++++++++++++++++++++++ device_test.go | 23 +++++++++++++++++++++++ grpc.go | 3 +++ 3 files changed, 52 insertions(+) diff --git a/device.go b/device.go index 3b0307f975..ec1907e0b2 100644 --- a/device.go +++ b/device.go @@ -34,6 +34,7 @@ const ( driverNvdimmType = "nvdimm" driverEphemeralType = "ephemeral" driverLocalType = "local" + vmRootfs = "/" ) const ( @@ -472,3 +473,28 @@ func addDevice(ctx context.Context, device *pb.Device, spec *pb.Spec, s *sandbox return devHandler(ctx, *device, spec, s) } + +// updateDeviceCgroupForGuestRootfs updates the device cgroup for container +// to not allow access to the nvdim root partition. This prevents the container +// from being able to access the VM rootfs. +func updateDeviceCgroupForGuestRootfs(spec *pb.Spec) { + var devStat unix.Stat_t + + err := unix.Stat(vmRootfs, &devStat) + if err != nil { + return + } + + devMajor := int64(unix.Major(devStat.Dev)) + devMinor := int64(unix.Minor(devStat.Dev)) + + nvdimmCg := pb.LinuxDeviceCgroup{ + Allow: false, + Major: devMajor, + Minor: devMinor, + Type: "b", + Access: "rwm", + } + + spec.Linux.Resources.Devices = append(spec.Linux.Resources.Devices, nvdimmCg) +} diff --git a/device_test.go b/device_test.go index 8c8f201930..72a9dac1d9 100644 --- a/device_test.go +++ b/device_test.go @@ -18,6 +18,7 @@ import ( pb "github.com/kata-containers/agent/protocols/grpc" "github.com/stretchr/testify/assert" + "golang.org/x/sys/unix" ) var ( @@ -728,3 +729,25 @@ func TestGetDeviceName(t *testing.T) { assert.Nil(err) assert.Equal(name, path.Join(devRootPath, devName)) } + +func TestUpdateDeviceCgroupForGuestRootfs(t *testing.T) { + skipUnlessRoot(t) + assert := assert.New(t) + + spec := &pb.Spec{} + + spec.Linux = &pb.Linux{} + spec.Linux.Resources = &pb.LinuxResources{} + + updateDeviceCgroupForGuestRootfs(spec) + assert.Equal(1, len(spec.Linux.Resources.Devices)) + + var devStat unix.Stat_t + err := unix.Stat(vmRootfs, &devStat) + if err != nil { + return + } + + assert.Equal(spec.Linux.Resources.Devices[0].Major, int64(unix.Major(devStat.Dev))) + assert.Equal(spec.Linux.Resources.Devices[0].Minor, int64(unix.Minor(devStat.Dev))) +} diff --git a/grpc.go b/grpc.go index 8a0dffddc6..829881f12f 100644 --- a/grpc.go +++ b/grpc.go @@ -654,6 +654,9 @@ func (a *agentGRPC) CreateContainer(ctx context.Context, req *pb.CreateContainer } }() + // Add the nvdimm root partition to the device cgroup to prevent access + updateDeviceCgroupForGuestRootfs(req.OCI) + // Convert the spec to an actual OCI specification structure. ociSpec, err := pb.GRPCtoOCI(req.OCI) if err != nil {