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:
- 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"
]
}
]
- 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.
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 likecgroup,mqueue,sysfs, andtmpfs, the unvalidated string is passed down to themount(2)syscall, causing the kernel to return anEINVAL(Invalid Argument) error.(For context,
youkiv0.6.0 exhibits similar behavior, whereascrunv1.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
\u0000in 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:
config.jsonsnippet where\u0000is injected into the mount options:config.json snippet
sudo):Bash
Current Logs and Outputs:
Currently, the runtime passes the string to the kernel and crashes with a syscall error.
Plaintext
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.