-
Notifications
You must be signed in to change notification settings - Fork 194
Description
Starting with Docker v24.0, running --net=host fails if Docker is run inside a sysbox container.
I've raised a Docker issue, and bisected the problem to this Docker commit.
The outer Docker version doesn't seem to matter, and I've verified the problem on Sysbox CE 0.5.2 and 0.6.2.
The new version of Docker attempts to bind-mount /proc/self/task/<tid>/ns/net and this fails with "permission denied". Curiously, if I modify the Docker code to bind-mount /proc/thread-self/ns/net this succeeds. However, this is not a viable solution for Docker, because /proc/thread-self is unsupported on older kernels that Docker still supports.
Below is a minimal Go program that can test bind-mounting in the way Docker does:
package main
import (
"runtime"
"fmt"
"syscall"
"os"
)
func main() {
runtime.LockOSThread()
fmt.Printf("uid: %d\n", syscall.Getuid())
basePath := "/proc/self/task/%d/ns/net", syscall.Gettid())
fmt.Println(basePath)
lnPath := "/var/namespace/test"
f, err := os.Create(lnPath)
if err != nil {
fmt.Printf("failed to create %s: %s\n", lnPath, err)
os.Exit(1)
}
f.Close()
err = syscall.Mount(basePath, lnPath, "bind", syscall.MS_BIND, "")
if err != nil {
fmt.Printf("failed to bind-mount %s: %s\n", basePath, err)
os.Exit(1)
}
runtime.UnlockOSThread()
}When I run it as root inside a sysbox 0.6.2 container, it fails with "permission denied." If I switch basePath to be /proc/thread-self/ns/net it succeeds.
It also succeeds if I run it in a combination of user and mount namespaces, e.g. unshare --user --mount --map-root-user ./bmount. Using unshare both the /proc/self/task/<tid> and /proc/thread-self variants succeed. However, if I unshare with only a user namespace (no mount namespace), both variants fail with permission denied.
Sysbox is the only environment I've found where /proc/thread-self succeeds, and /proc/self/task/<tid> fails. So, something more subtle than just user namespace isolation is going on.