for-linux icon indicating copy to clipboard operation
for-linux copied to clipboard

[Bug] SLCAND not working inside container with standard network

Open JanJamaszyk-FlyNow opened this issue 5 years ago • 5 comments

  • [x] This is a bug report
  • [ ] This is a feature request
  • [x] I searched existing issues before opening this one

Expected behavior

When container is started with --net=host:

sudo slcand -o -s6 -t hw -S 115200 -F /dev/slcan2usb slcan1
[6] starting on TTY device /dev/slcan2usb
[5] attached TTY /dev/slcan2usb to netdevice slcan0

 

[5] netdevice slcan0 renamed to slcan1

Actual behavior

When container is started without --net=host:

sudo slcand -o -s6 -t hw -S 115200 -F /dev/slcan2usb slcan1
[6] starting on TTY device /dev/slcan2usb
[5] attached TTY /dev/slcan2usb to netdevice slcan0

 

[5] netdevice slcan0 rename to slcan1 failed

 

ioctl SIOCSIFNAME rename: No such device

If we look into the source-code of slcand it seems as if ioctl(fd, SIOCGIFNAME, ifr.ifr_name) returns a value >= 0 while not actually creating the device. Hence the log-message: ioctl SIOCSIFNAME rename: No such device is triggered by ioctl(s, SIOCSIFNAME, &ifr) < 0 from here.

Steps to reproduce the behavior

  1. Connect an SLCAN compatible USB to CAN interface
  2. Use Ubuntu 20.04 Base Image
  3. Map the serial device into the docker container
  4. Start slcand as described above

Output of docker version:

docker version
Client: Docker Engine - Community
 Version:           20.10.2
 API version:       1.41
 Go version:        go1.13.15
 Git commit:        2291f61
 Built:             Mon Dec 28 16:17:43 2020
 OS/Arch:           linux/amd64
 Context:           default
 Experimental:      true

 

Server: Docker Engine - Community
 Engine:
  Version:          20.10.2
  API version:      1.41 (minimum version 1.12)
  Go version:       go1.13.15
  Git commit:       8891c58
  Built:            Mon Dec 28 16:15:19 2020
  OS/Arch:          linux/amd64
  Experimental:     false
 containerd:
  Version:          1.4.3
  GitCommit:        269548fa27e0089a8b8278fc4fc781d7f65a939b
 runc:
  Version:          1.0.0-rc92
  GitCommit:        ff819c7e9184c13b7c2607fe6c30ae19403a7aff
 docker-init:
  Version:          0.19.0
  GitCommit:        de40ad0

Output of docker info:

docker info
Client:
 Context:    default
 Debug Mode: false
 Plugins:
  app: Docker App (Docker Inc., v0.9.1-beta3)
  buildx: Build with BuildKit (Docker Inc., v0.5.1-docker)

 

Server:
 Containers: 3
  Running: 0
  Paused: 0
  Stopped: 3
 Images: 1044
 Server Version: 20.10.2
 Storage Driver: overlay2
  Backing Filesystem: extfs
  Supports d_type: true
  Native Overlay Diff: true
 Logging Driver: json-file
 Cgroup Driver: cgroupfs
 Cgroup Version: 1
 Plugins:
  Volume: local
  Network: bridge host ipvlan macvlan null overlay
  Log: awslogs fluentd gcplogs gelf journald json-file local logentries splunk syslog
 Swarm: inactive
 Runtimes: io.containerd.runtime.v1.linux nvidia runc io.containerd.runc.v2
 Default Runtime: runc
 Init Binary: docker-init
 containerd version: 269548fa27e0089a8b8278fc4fc781d7f65a939b
 runc version: ff819c7e9184c13b7c2607fe6c30ae19403a7aff
 init version: de40ad0
 Security Options:
  apparmor
  seccomp
   Profile: default
 Kernel Version: 5.8.0-36-generic
 Operating System: Ubuntu 20.04.1 LTS
 OSType: linux
 Architecture: x86_64
 CPUs: 16
 Total Memory: 31.23GiB
 Name: Flyn
 ID: WLLG:E3F3:24ZK:VEIZ:ZYPB:467N:QACM:4CNU:QALK:L6D4:LJDF:YYGT
 Docker Root Dir: /var/lib/docker
 Debug Mode: false
 Registry: https://index.docker.io/v1/
 Labels:
 Experimental: false
 Insecure Registries:
  127.0.0.0/8
 Live Restore Enabled: false
 Default Address Pools:
   Base: 182.240.0.0/16, Size: 24

 

WARNING: No blkio weight support
WARNING: No blkio weight_device support

JanJamaszyk-FlyNow avatar Jan 13 '21 14:01 JanJamaszyk-FlyNow

I've observed that the network interface is actually visible on the host instead of inside the Docker container when started without --net=host.

JustinOng avatar Jun 07 '21 14:06 JustinOng

Wow, good catch Justin! If I understand this correctly this means that we found a security issue where the container can influence the host environment!

JanJamaszyk-FlyNow avatar Jun 07 '21 15:06 JanJamaszyk-FlyNow

I don't think this is a security issue. My previous observation was made on a container started with --privileged and -v /dev:/dev.

Passing only --device /dev/ttyUSBS0, I get:

***@***.***:/# slcand -s8 -S 115200 /dev/ttyUSB0 -F
[6] starting on TTY device /dev/ttyUSB0
ioctl TIOCSETD: Operation not permitted

On Mon, Jun 7, 2021 at 11:31 PM Jan Jamaszyk @.***> wrote:

Wow, good catch Justin! If I understand this correctly this means that we found a security issue where the container can influence the host environment!

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/docker/for-linux/issues/1184#issuecomment-856037862, or unsubscribe https://github.com/notifications/unsubscribe-auth/ACHHNG7TRX7LGHRJRNG5OLDTRTQ3PANCNFSM4WA5OIOQ .

JustinOng avatar Jun 08 '21 10:06 JustinOng

I can still reproduce this.

Using --device, I get a privilege error when setting the line discipline

> docker run -it --device=/dev/ttyACM0 debian bash
> apt update
> apt install can-utils
> slcand -S 3000000 /dev/ttyACM0
# ioctl TIOCSETD: Operation not permitted

Using --privileged, slcand succeeds except the network device is created on the host and not in the container.

> docker run -it --privileged debian bash
> apt update
> apt install can-utils iproute2
> slcand -S 3000000 /dev/ttyACM0
> ip link
## No can interface

On the host machine with the privileged container still running

> ip link
## Shows can0 interface
> sudo ip link set up can0
> candump can0
## Outputs can data

Note that I ensured can0 on the host machine did not exist before running the privileged container and stopped existing once the container was exited.

Passing --net=host gives the container access to the can0 interface it created, as would be expected.

Output of docker version

Client: Docker Engine - Community
 Version:           24.0.7
 API version:       1.43
 Go version:        go1.20.10
 Git commit:        afdd53b
 Built:             Thu Oct 26 09:08:02 2023
 OS/Arch:           linux/amd64
 Context:           default

Server: Docker Engine - Community
 Engine:
  Version:          24.0.7
  API version:      1.43 (minimum version 1.12)
  Go version:       go1.20.10
  Git commit:       311b9ff
  Built:            Thu Oct 26 09:08:02 2023
  OS/Arch:          linux/amd64
  Experimental:     false
 containerd:
  Version:          1.6.24
  GitCommit:        61f9fd88f79f081d64d6fa3bb1a0dc71ec870523
 runc:
  Version:          1.1.9
  GitCommit:        v1.1.9-0-gccaecfc
 docker-init:
  Version:          0.19.0
  GitCommit:        de40ad0

levivk avatar Nov 06 '23 17:11 levivk

Interestingly, pppd creates a network interface inside of a privileged container just fine.

> docker run -it --privileged debian bash
> apt update
> apt install ppp iproute2
> pppd /dev/ttyACM0 noauth
> ip link
## shows interface ppp0

levivk avatar Nov 06 '23 18:11 levivk