opencontainers / opencontainers/runc

Validate mount options for null bytes (\u0000) early to provide clearer error messages

Open
#5,320 7 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Go
Stars
13.5k
Forks
2.3k
Avg merge
2d 8h
Merged PRs (30d)
30

Description

Description: I noticed that while runc (v1.4.2) correctly rejects mount options containing null bytes (\u0000), the failure occurs very late in the lifecycle—at the syscall level—resulting in a somewhat generic and cryptic error.

When injecting a null byte into mount options (e.g., nosuid\u0000) for filesystems like cgroup, mqueue, sysfs, and tmpfs, the unvalidated string is passed down to the mount(2) syscall, causing the kernel to return an EINVAL (Invalid Argument) error.

(For context, youki v0.6.0 exhibits similar behavior, whereas crun v1.28 silently strips everything after the null byte and proceeds).

The Proposal: It might be beneficial to add early validation during the configuration parsing phase. If the parser explicitly checks for and rejects \u0000 in mount options, it could return a much more actionable and user-friendly error message (e.g., Error: mount option 'nosuid\u0000' contains illegal null byte), rather than relying on the kernel to catch it.

Steps to reproduce:

  1. Use the following config.json snippet where \u0000 is injected into the mount options:

config.json snippet

"mounts": [
    {
        "destination": "/proc",
        "type": "proc",
        "source": "proc"
    },
    {
        "destination": "/dev",
        "type": "tmpfs",
        "source": "tmpfs",
        "options": [
            "nosuid",
            "strictatime",
            "mode=755",
            "size=65536k"
        ]
    },
    {
        "destination": "/dev/pts",
        "type": "devpts",
        "source": "devpts",
        "options": [
            "nosuid",
            "noexec",
            "newinstance",
            "ptmxmode=0666",
            "mode=0620",
            "gid=5"
        ]
    },
    {
        "destination": "/dev/shm",
        "type": "tmpfs",
        "source": "shm",
        "options": [
            "nosuid",
            "noexec",
            "nodev",
            "mode=1777",
            "size=65536k"
        ]
    },
    {
        "destination": "/dev/mqueue",
        "type": "mqueue",
        "source": "mqueue",
        "options": [
            "nosuid",
            "noexec",
            "nodev"
        ]
    },
    {
        "destination": "/sys",
        "type": "sysfs",
        "source": "sysfs",
        "options": [
            "nosuid",
            "noexec",
            "nodev",
            "ro"
        ]
    },
    {
        "destination": "/sys/fs/cgroup",
        "type": "cgroup2",
        "source": "cgroup2",
        "options": [
            "nosuid\u0000",
            "noexec",
            "nodev",
            "relatime",
            "ro",
            "nsdelegate"
        ]
    }
]
  1. Run the container creation command (using sudo):

Bash

sudo runc create mycontainer

Current Logs and Outputs:

Currently, the runtime passes the string to the kernel and crashes with a syscall error.

Plaintext

ERRO[0000] runc create failed: unable to start container process: error during container init: error mounting "cgroup2" to rootfs at "/sys/fs/cgroup": mount src=cgroup2, dst=/sys/fs/cgroup, dstFd=/proc/thread-self/fd/11, flags=MS_RDONLY|MS_NODEV|MS_NOEXEC|MS_RELATIME, data=nosuid,nsdelegate: invalid argument

Expected Behavior:

The runtime should catch the null byte during the spec validation phase (before executing syscalls) and print a clear error indicating that null bytes are not allowed in string parameters.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Trace the configuration parsing and mount-option handling used by runc create, starting with the spec validation path and the code that prepares mount data. Add early rejection for null bytes with a clear error, then run the supplied config.json reproduction and verify that validation fails before the mount syscall.

Written by the indexing model from the issue text.

Assessment

Tech stack
go
Domain
infrastructure, operating-systems
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
64/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.