spec: always specify default rlimits

the previous implementation was expecting the rlimits to be set for the
entire process and clamping the values only when running as rootless.

Change the implementation to always specify the expected values in the
OCI spec file and do the clamping only when running as rootless and
using the default values.

Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>
This commit is contained in:
Giuseppe Scrivano 2024-10-10 17:35:44 +02:00
parent 8896ace2a4
commit 5ebba75dbd
No known key found for this signature in database
GPG Key ID: 67E38F7A8BA21772
2 changed files with 23 additions and 16 deletions

View File

@ -14,6 +14,11 @@ $ podman run --ulimit nofile=1024:1024 --rm ubi9 ulimit -n
Set -1 for the soft or hard limit to set the limit to the maximum limit of the current Set -1 for the soft or hard limit to set the limit to the maximum limit of the current
process. In rootful mode this is often unlimited. process. In rootful mode this is often unlimited.
If nofile and nproc are unset, a default value of 1048576 will be used, unless overridden
in containers.conf(5). However, if the default value exceeds the hard limit for the current
rootless user, the current hard limit will be applied instead.
Use **host** to copy the current configuration from the host. Use **host** to copy the current configuration from the host.
Don't use nproc with the ulimit flag as Linux uses nproc to set the Don't use nproc with the ulimit flag as Linux uses nproc to set the

View File

@ -671,18 +671,18 @@ func (c *Container) generateSpec(ctx context.Context) (s *spec.Spec, cleanupFunc
return nil, nil, err return nil, nil, err
} }
} }
if isRootless { for _, rlimit := range c.config.Spec.Process.Rlimits {
for _, rlimit := range c.config.Spec.Process.Rlimits { if rlimit.Type == "RLIMIT_NOFILE" {
if rlimit.Type == "RLIMIT_NOFILE" { nofileSet = true
nofileSet = true
}
if rlimit.Type == "RLIMIT_NPROC" {
nprocSet = true
}
} }
if !nofileSet { if rlimit.Type == "RLIMIT_NPROC" {
max := rlimT(define.RLimitDefaultValue) nprocSet = true
current := rlimT(define.RLimitDefaultValue) }
}
if !nofileSet {
max := rlimT(define.RLimitDefaultValue)
current := rlimT(define.RLimitDefaultValue)
if isRootless {
var rlimit unix.Rlimit var rlimit unix.Rlimit
if err := unix.Getrlimit(unix.RLIMIT_NOFILE, &rlimit); err != nil { if err := unix.Getrlimit(unix.RLIMIT_NOFILE, &rlimit); err != nil {
logrus.Warnf("Failed to return RLIMIT_NOFILE ulimit %q", err) logrus.Warnf("Failed to return RLIMIT_NOFILE ulimit %q", err)
@ -693,11 +693,13 @@ func (c *Container) generateSpec(ctx context.Context) (s *spec.Spec, cleanupFunc
if rlimT(rlimit.Max) < max { if rlimT(rlimit.Max) < max {
max = rlimT(rlimit.Max) max = rlimT(rlimit.Max)
} }
g.AddProcessRlimits("RLIMIT_NOFILE", uint64(max), uint64(current))
} }
if !nprocSet { g.AddProcessRlimits("RLIMIT_NOFILE", uint64(max), uint64(current))
max := rlimT(define.RLimitDefaultValue) }
current := rlimT(define.RLimitDefaultValue) if !nprocSet {
max := rlimT(define.RLimitDefaultValue)
current := rlimT(define.RLimitDefaultValue)
if isRootless {
var rlimit unix.Rlimit var rlimit unix.Rlimit
if err := unix.Getrlimit(unix.RLIMIT_NPROC, &rlimit); err != nil { if err := unix.Getrlimit(unix.RLIMIT_NPROC, &rlimit); err != nil {
logrus.Warnf("Failed to return RLIMIT_NPROC ulimit %q", err) logrus.Warnf("Failed to return RLIMIT_NPROC ulimit %q", err)
@ -708,8 +710,8 @@ func (c *Container) generateSpec(ctx context.Context) (s *spec.Spec, cleanupFunc
if rlimT(rlimit.Max) < max { if rlimT(rlimit.Max) < max {
max = rlimT(rlimit.Max) max = rlimT(rlimit.Max)
} }
g.AddProcessRlimits("RLIMIT_NPROC", uint64(max), uint64(current))
} }
g.AddProcessRlimits("RLIMIT_NPROC", uint64(max), uint64(current))
} }
c.addMaskedPaths(&g) c.addMaskedPaths(&g)