podman: /libpod/networks/create API generates broken conflist on non-conforming Mask values

/kind bug

Description

A valid request body to the create network API looks like:

{"Subnet":{"IP":"10.10.1.0","Mask":"////AA=="}}

Note that Mask is decoded as base64. If the Mask can decode, but isn’t an expected bitmask afterwards, Podman stores an invalid conflist to disk.

Bodies that are accepted and produce an invalid conflist include:

  • {"Subnet":{"IP":"10.10.1.0","Mask":"ffffff80"}}
  • {"Subnet":{"IP":"10.10.1.0","Mask":""}}
  • {"Subnet":{"IP":"10.10.1.0","Mask":"aaaaaaaaaaaaaaaaaaaa"}}

Steps to reproduce the issue:

  1. sudo podman system service -t 30 tcp:127.0.0.1:8410

  2. curl -H 'Content-type: application/json' -XPOST http://localhost:8410/v1.0.0/libpod/networks/create --data '{"Subnet":{"IP":"10.10.1.0","Mask":""}}'

  3. curl http://localhost:8410/v1.0.0/libpod/networks/testnet/json

Describe the results you received:

[{"cniVersion":"0.4.0","name":"testnet","plugins":[{"bridge":"cni-podman1","hairpinMode":true,"ipMasq":true,"ipam":{"ranges":[[{"gateway":"?01","subnet":"\u003cnil\u003e"}]],"routes":[{"dst":"0.0.0.0/0"}],"type":"host-local"},"isGateway":true,"type":"bridge"},{"capabilities":{"portMappings":true},"type":"portmap"},{"backend":"","type":"firewall"},{"domainName":"dns.podman","type":"dnsname"}]}]

In particular: {"gateway":"?01","subnet":"\u003cnil\u003e"}

Describe the results you expected:

An error message on creation.

Additional information you deem important (e.g. issue happens only occasionally):

Nothing in the API docs says that Mask should be base64. https://docs.podman.io/en/latest/_static/api.html#operation/libpodCreateNetwork

With the invalid network created, the list and describe APIs show the invalid network config. However, creating new networks no longer works. The error payload is simply {"cause":"invalid IP address: ?01","message":"invalid IP address: ?01","response":500}. It seems that creating a new network has the effect of performing extra checks on all existing conflists.

Output of podman version:

Version:      2.0.4
API Version:  1
Go Version:   go1.14
Built:        Thu Jan  1 01:00:00 1970
OS/Arch:      linux/amd64

Output of podman info --debug:

host:
  arch: amd64
  buildahVersion: 1.15.0
  cgroupVersion: v1
  conmon:
    package: 'conmon: /usr/libexec/podman/conmon'
    path: /usr/libexec/podman/conmon
    version: 'conmon version 2.0.18, commit: '
  cpus: 2
  distribution:
    distribution: debian
    version: "10"
  eventLogger: file
  hostname: penguin
  idMappings:
    gidmap: null
    uidmap: null
  kernel: 5.4.40-04224-g891a6cce2d44
  linkmode: dynamic
  memFree: 15240572928
  memTotal: 15260385280
  ociRuntime:
    name: runc
    package: 'runc: /usr/sbin/runc'
    path: /usr/sbin/runc
    version: |-
      runc version 1.0.0~rc6+dfsg1
      commit: 1.0.0~rc6+dfsg1-3
      spec: 1.0.1
  os: linux
  remoteSocket:
    path: /run/podman/podman.sock
  rootless: false
  slirp4netns:
    executable: ""
    package: ""
    version: ""
  swapFree: 0
  swapTotal: 0
  uptime: 23h 1m 45s (Approximately 0.96 days)
registries:
  search:
  - docker.io
  - quay.io
store:
  configFile: /etc/containers/storage.conf
  containerStore:
    number: 0
    paused: 0
    running: 0
    stopped: 0
  graphDriverName: btrfs
  graphOptions: {}
  graphRoot: /var/lib/containers/storage
  graphStatus:
    Build Version: 'Btrfs v5.2.1 '
    Library Version: "102"
  imageStore:
    number: 2
  runRoot: /var/run/containers/storage
  volumePath: /var/lib/containers/storage/volumes
version:
  APIVersion: 1
  Built: 0
  BuiltTime: Thu Jan  1 01:00:00 1970
  GitCommit: ""
  GoVersion: go1.14
  OsArch: linux/amd64
  Version: 2.0.4

Package info (e.g. output of rpm -q podman or apt list podman):

podman/unknown,now 2.0.4~1 amd64 [installed]

Additional environment details (AWS, VirtualBox, physical, etc.):

lxc container (Chromebook Linux Beta)

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Comments: 26 (11 by maintainers)

Most upvoted comments

Ideally these would both be strings, but that would also technically be a breaking API change.

At this point, I think we add validation to subnet to ensure it is valid, update the documentation to indicate the correct types, and change both to a string next time we make a breaking change to the API.

This should be fixed on main