Skip to content

[FEATURE]: Validate mount options for null bytes (\u0000) early to provide clearer error messages #3591

@74suiko

Description

@74suiko

Background

I noticed that while youki (v0.6.0) correctly rejects mount options containing null bytes (\u0000), the failure occurs very late in the lifecycle—at the syscall level.

Feature Request

Add early validation during the configuration parsing phase to explicitly check for and reject null bytes (\u0000) in string parameters like mount options, rather than passing them down to the syscall level.

Is the request related to some problem running youki?

Yes. 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. This results in a somewhat generic and cryptic error.
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 youki create mycontainer

Current Logs and Outputs:

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

Plaintext

ERROR libcontainer::rootfs::mount: failed to mount Mount { destination: "/sys/fs/cgroup", typ: Some("cgroup2"), source: Some("cgroup2"), options: Some(["nosuid\0", "noexec", "nodev", "relatime", "ro", "nsdelegate"]), uid_mappings: None, gid_mappings: None }: syscall
ERROR libcontainer::process::init::process: failed to prepare rootfs err=Mount(Syscall(Nix(EINVAL)))
ERROR libcontainer::process::container_intermediate_process: failed to initialize container process: failed to prepare rootfs

Proposed Solution

Ideally, the runtime should catch the null byte during the spec validation phase (before executing syscalls) and print a much more actionable and user-friendly error message, such as:
Error: mount option 'nosuid\u0000' contains illegal null byte.

Considerations

Relying on the kernel to catch it (current behavior) is secure but provides poor UX.
(For context, runc v1.4.2 exhibits similar behavior by crashing at the syscall level, whereas crun v1.28 silently strips everything after the null byte and proceeds, which poses a configuration fidelity risk). Implementing early validation would make youki both secure and more user-friendly than the alternatives.

Additional Context

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions