mirror of
https://github.com/opencontainers/runc.git
synced 2026-02-06 21:45:21 +01:00
Fixes inability to use /dev/null when inside a container
This is a forward port of https://github.com/opencontainers/runc/pull/3620
The original code depended on the origin filesystem to have
/dev/{block,char} populated. This is done by udev normally and while is
very common non-containerized systemd installs, it's very easy to start
systemd in a container created by runc itself and not have
/dev/{block,char} populated. When this occurs, the following error
output is observed:
$ docker run hello-world
docker: Error response from daemon: failed to create shim task: OCI runtime create failed: runc create failed: unable to start container process: error during container init: error reopening /dev/null inside container: open /dev/null: operation not permitted: unknown.
/dev/null can't be opened because it was not added to the
deviceAllowList, as there was no /dev/char directory. The change here
utilizes the fact that when sysfs in in use, there is a
/sys/dev/{block,char} that is kernel maintained that we can check.
Signed-off-by: Evan Phoenix <evan@phx.io>
(cherry picked from commit 462e719cae)
This commit is contained in:
@@ -293,8 +293,18 @@ func generateDeviceProperties(r *configs.Resources) ([]systemdDbus.Property, err
|
||||
// rules separately to systemd) we can safely skip entries that don't
|
||||
// have a corresponding path.
|
||||
if _, err := os.Stat(entry.Path); err != nil {
|
||||
logrus.Debugf("skipping device %s for systemd: %s", entry.Path, err)
|
||||
continue
|
||||
// Also check /sys/dev so that we don't depend on /dev/{block,char}
|
||||
// being populated. (/dev/{block,char} is populated by udev, which
|
||||
// isn't strictly required for systemd). Ironically, this happens most
|
||||
// easily when starting containerd within a runc created container
|
||||
// itself.
|
||||
|
||||
// We don't bother with securejoin here because we create entry.Path
|
||||
// right above here, so we know it's safe.
|
||||
if _, err := os.Stat("/sys" + entry.Path); err != nil {
|
||||
logrus.Warnf("skipping device %s for systemd: %s", entry.Path, err)
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
deviceAllowList = append(deviceAllowList, entry)
|
||||
|
||||
Reference in New Issue
Block a user