kata-containers/agent

Updating linux resource fields may clobber itself

dgibson opened this issue · 2 comments

Description of problem

This bug was seen by code inspection, I haven't reproduced it (but I'm pretty sure it could be with careful selection of configuration + some bad luck).

The problem arises if all of these conditions occur:

  • Two devices (say /dev/a and /dev/b) are configured for the container in the OCI specification
  • Both devices are of types which are processed by updateSpecDeviceList in the agent
  • /dev/a has an entry (selected by type/major/minor) in the resouces::devices section of the OCI container configuration
  • By coincidence /dev/a in the VM has the same major/minor numbers as /dev/b does in the host

Expected result

The permissions configured for for /dev/a will be correctly applied in the guest container for /dev/a

Actual result

The permissions configured for /dev/a will be incorrectly applied to /dev/b in the container.

More details

The problem occurs because we match resource entries by major/minor (from the host), updating them for the guest as we go.

So, when we call updateSpecDeviceList for /dev/a, we find the entry for /dev/a in the resources, and update it to the guest major/minor for /dev/a. But that happens to be the same values as the host major/minor for /dev/b, so when we call updateSpecDeviceList for /dev/b we incorrectly assume the already updated entry is for /dev/a is actually for /dev/b and update it a second time.

c3d commented

Looking at the code, I agree this is problematic. The Linux structure has a single Devices list, and it's straight from the OCI spec. So there is no natural place to put a "guest device" in there.

Fortunately, Major and Minor are int64, which is way too large for a major/minor on Linux. So maybe we could use one of the high bits to indicate "guest device"? The Unix.Major and Unix.Minor filter out these bits, so we can use them somewhat freely if we are careful.

I've already implemented a very different approach in #836