diff options
author | Valentin Rothberg <rothberg@redhat.com> | 2021-10-29 10:28:38 +0200 |
---|---|---|
committer | Valentin Rothberg <rothberg@redhat.com> | 2021-11-08 13:33:30 +0100 |
commit | 6444f2402839330f977cfe1c701ca331a915047b (patch) | |
tree | 5ac9d000ab787608ddac3617977d3e84579a4dd3 /libpod/runtime_pod_linux.go | |
parent | 865653b661dd9dbc5d31f08cbf3f14ed32c82850 (diff) | |
download | podman-6444f2402839330f977cfe1c701ca331a915047b.tar.gz podman-6444f2402839330f977cfe1c701ca331a915047b.tar.bz2 podman-6444f2402839330f977cfe1c701ca331a915047b.zip |
pod/container create: resolve conflicts of generated names
Address the TOCTOU when generating random names by having at most 10
attempts to assign a random name when creating a pod or container.
[NO TESTS NEEDED] since I do not know a way to force a conflict with
randomly generated names in a reasonable time frame.
Fixes: #11735
Signed-off-by: Valentin Rothberg <rothberg@redhat.com>
Diffstat (limited to 'libpod/runtime_pod_linux.go')
-rw-r--r-- | libpod/runtime_pod_linux.go | 40 |
1 files changed, 26 insertions, 14 deletions
diff --git a/libpod/runtime_pod_linux.go b/libpod/runtime_pod_linux.go index 7d7fef4d1..15050ef48 100644 --- a/libpod/runtime_pod_linux.go +++ b/libpod/runtime_pod_linux.go @@ -43,18 +43,6 @@ func (r *Runtime) NewPod(ctx context.Context, p specgen.PodSpecGenerator, option } } - if pod.config.Name == "" { - name, err := r.generateName() - if err != nil { - return nil, err - } - pod.config.Name = name - } - - if p.InfraContainerSpec != nil && p.InfraContainerSpec.Hostname == "" { - p.InfraContainerSpec.Hostname = pod.config.Name - } - // Allocate a lock for the pod lock, err := r.lockManager.AllocateLock() if err != nil { @@ -131,9 +119,33 @@ func (r *Runtime) NewPod(ctx context.Context, p specgen.PodSpecGenerator, option logrus.Infof("Pod has an infra container, but shares no namespaces") } - if err := r.state.AddPod(pod); err != nil { - return nil, errors.Wrapf(err, "error adding pod to state") + // Unless the user has specified a name, use a randomly generated one. + // Note that name conflicts may occur (see #11735), so we need to loop. + generateName := pod.config.Name == "" + var addPodErr error + for { + if generateName { + name, err := r.generateName() + if err != nil { + return nil, err + } + pod.config.Name = name + } + + if p.InfraContainerSpec != nil && p.InfraContainerSpec.Hostname == "" { + p.InfraContainerSpec.Hostname = pod.config.Name + } + if addPodErr = r.state.AddPod(pod); addPodErr == nil { + return pod, nil + } + if !generateName || (errors.Cause(addPodErr) != define.ErrPodExists && errors.Cause(addPodErr) != define.ErrCtrExists) { + break + } + } + if addPodErr != nil { + return nil, errors.Wrapf(addPodErr, "error adding pod to state") } + return pod, nil } |