specgen: parse devices even with privileged set

When a users asks for specific devices we should still add them and not
ignore them just because privileged adds all of them.

Most notably if you set --device /dev/null:/dev/test you expect
/dev/test in the container, however as we ignored them this was not the
case. Another side effect is that the input was not validated at at all.
This leads to confusion as descriped in the issue.

Fixes #23132

Signed-off-by: Paul Holzinger <pholzing@redhat.com>
This commit is contained in:
Paul Holzinger
2024-06-28 16:14:28 +02:00
parent 8650348bc9
commit 83863a6863
3 changed files with 27 additions and 18 deletions

View File

@ -254,24 +254,21 @@ func SpecGenToOCI(ctx context.Context, s *specgen.SpecGenerator, rt *libpod.Runt
}
var userDevices []spec.LinuxDevice
if !s.IsPrivileged() {
// add default devices from containers.conf
for _, device := range rtc.Containers.Devices.Get() {
if err = DevicesFromPath(&g, device); err != nil {
return nil, err
}
// add default devices from containers.conf
for _, device := range rtc.Containers.Devices.Get() {
if err = DevicesFromPath(&g, device); err != nil {
return nil, err
}
if len(compatibleOptions.HostDeviceList) > 0 && len(s.Devices) == 0 {
userDevices = compatibleOptions.HostDeviceList
} else {
userDevices = s.Devices
}
// add default devices specified by caller
for _, device := range userDevices {
if err = DevicesFromPath(&g, device.Path); err != nil {
return nil, err
}
}
if len(compatibleOptions.HostDeviceList) > 0 && len(s.Devices) == 0 {
userDevices = compatibleOptions.HostDeviceList
} else {
userDevices = s.Devices
}
// add default devices specified by caller
for _, device := range userDevices {
if err = DevicesFromPath(&g, device.Path); err != nil {
return nil, err
}
}
s.HostDeviceList = userDevices

View File

@ -106,7 +106,6 @@ func AddPrivilegedDevices(g *generate.Generator, systemdMode bool) error {
if err != nil {
return err
}
g.ClearLinuxDevices()
if rootless.IsRootless() {
mounts := make(map[string]interface{})

View File

@ -1687,6 +1687,19 @@ VOLUME %s`, ALPINE, volPath, volPath)
Expect(session).Should(ExitCleanly())
})
It("podman run --device and --privileged", func() {
session := podmanTest.Podman([]string{"run", "--device", "/dev/null:/dev/testdevice", "--privileged", ALPINE, "ls", "/dev"})
session.WaitWithDefaultTimeout()
Expect(session).Should(ExitCleanly())
Expect(session.OutputToString()).To(ContainSubstring(" testdevice "), "our custom device")
// assumes that /dev/mem always exists
Expect(session.OutputToString()).To(ContainSubstring(" mem "), "privileged device")
session = podmanTest.Podman([]string{"run", "--device", "invalid-device", "--privileged", ALPINE, "ls", "/dev"})
session.WaitWithDefaultTimeout()
Expect(session).Should(ExitWithError(125, "stat invalid-device: no such file or directory"))
})
It("podman run --replace", func() {
// Make sure we error out with --name.
session := podmanTest.Podman([]string{"create", "--replace", ALPINE, "/bin/sh"})