libnetwork/pasta: fix --map-gw parsing

If a port option was given after --map-gw then parsing failed as the
next arg was always skipped due the modification of the slice.

Modifing the slice inside the loop is bad and does not do what some
might think. Append here basically creates a new slice (thus you always
have to assign the result to the variable) with the same pointer to the
same underlying array of data[1]. The loop however will still continue to
loop over the slice as it saw it at the begining of the loop.

So in the bug case the underlying array would look like this:
{"--config-net", "--map-gw", "-T", "80"}
and after the append call to remove --map-gw like this:
{"--config-net", "-T", "80", "80"}

The loop iterator has no idea this happen and just moves to the next
index 2 ("80") and thus we never passed "-T" causing this bug.

[1] https://go.dev/blog/slices-intro

Fixes containers/podman#22477

Signed-off-by: Paul Holzinger <pholzing@redhat.com>
This commit is contained in:
Paul Holzinger 2024-04-24 13:40:23 +02:00
parent 27d56e6d8e
commit cced079805
2 changed files with 19 additions and 5 deletions

View File

@ -128,7 +128,7 @@ func createPastaArgs(opts *SetupOptions) ([]string, []string, error) {
noUDPInitPorts := true
noTCPNamespacePorts := true
noUDPNamespacePorts := true
noMapGW := true
noMapGWIndex := -1
cmdArgs := []string{"--config-net"}
@ -176,9 +176,7 @@ func createPastaArgs(opts *SetupOptions) ([]string, []string, error) {
case "-U", "--udp-ns":
noUDPNamespacePorts = false
case "--map-gw":
noMapGW = false
// not an actual pasta(1) option
cmdArgs = append(cmdArgs[:i], cmdArgs[i+1:]...)
noMapGWIndex = i
case dnsForwardOpt:
// if there is no arg after it pasta will likely error out anyway due invalid cli args
if len(cmdArgs) > i+1 {
@ -205,8 +203,11 @@ func createPastaArgs(opts *SetupOptions) ([]string, []string, error) {
if noUDPNamespacePorts {
cmdArgs = append(cmdArgs, "-U", "none")
}
if noMapGW {
if noMapGWIndex < 0 {
cmdArgs = append(cmdArgs, "--no-map-gw")
} else {
// not an actual pasta(1) option so we have to trim it out
cmdArgs = append(cmdArgs[:noMapGWIndex], cmdArgs[noMapGWIndex+1:]...)
}
// always pass --quiet to silence the info output from pasta

View File

@ -186,6 +186,19 @@ func Test_createPastaArgs(t *testing.T) {
},
wantDnsForward: []string{dnsForwardIpv4},
},
{
// https://github.com/containers/podman/issues/22477
name: "--map-gw with port directly after",
input: makeSetupOptions(nil,
[]string{"--map-gw", "-T", "80"},
nil,
),
wantArgs: []string{
"--config-net", "-T", "80", "--dns-forward", dnsForwardIpv4,
"-t", "none", "-u", "none", "-U", "none", "--quiet", "--netns", "netns123",
},
wantDnsForward: []string{dnsForwardIpv4},
},
{
name: "--dns-forward option",
input: makeSetupOptions(