Skip to content

namespaceTest compares UTS namespace instead of time namespace for TimeNamespace case #30

@abhaygoudannavar

Description

@abhaygoudannavar

Description

In tests/e2e/test_functions.go, the namespaceTest function has a copy-paste error in the specs.TimeNamespace switch case. It compares the UTS namespace (cntrNsMap["uts"]) instead of the time namespace, and reports the error as "uts:" instead of "time:".

This means time namespace isolation is never actually validated by the e2e test suite. The TimeNamespace case silently re-runs the exact same check as the UTSNamespace case above it, giving a false sense of test coverage.Additionally, the getProcNS() helper in tests/e2e/utils.go does not read the time_for_children symlink from /proc//ns/, so the time namespace data is not even available for comparison.

Root Cause

In tests/e2e/test_functions.go, the TimeNamespace case is a direct copy-paste of the UTSNamespace case without updating the namespace key or error label:

// correct UTS case
case specs.UTSNamespace:
    err = compareNS(cntrNsMap["uts"], selfNsMap["uts"], ns.Path)
    if err != nil {
        return fmt.Errorf("uts: %w", err)
    }
// broken Time case (identical to UTS above)
case specs.TimeNamespace:
    err = compareNS(cntrNsMap["uts"], selfNsMap["uts"], ns.Path)  // ← should be "time_for_children"
    if err != nil {
        return fmt.Errorf("uts: %w", err)  // ← should be "time:"
    }

Furthermore, getProcNS() in tests/e2e/utils.go reads cgroup, ipc, mnt, net, pid, user, and uts — but never reads time_for_children:

// utils.go:155-196 — getProcNS() namespace list
ns["cgroup"] = ...
ns["ipc"]    = ...
ns["mnt"]    = ...
ns["net"]    = ...
ns["pid"]    = ...
ns["user"]   = ...
ns["uts"]    = ...
//  missing: ns["time_for_children"]

Proposed Fix

  • Extend getProcNS() in utils.go to read the time namespace:
// Add after the "uts" readlink block (line ~193):
timePath := filepath.Join(procPath, "time_for_children")
ns["time_for_children"], err = os.Readlink(timePath)
if err != nil {
    return nil, err
}
  • Fix the TimeNamespace case in test_functions.go:
case specs.TimeNamespace:
    err = compareNS(cntrNsMap["time_for_children"], selfNsMap["time_for_children"], ns.Path)
    if err != nil {
        return fmt.Errorf("time: %w", err)
    }

System info

  • Repository: urunc_test
  • Files affected:
    1.tests/e2e/test_functions.go, lines 312-316
    2.tests/e2e/utils.go, lines 155-196
  • Arch: Any (bug is in test logic, not architecture-specific)
  • VMM: Any (bug affects all VMMs that use time namespaces)
  • Unikernel: Any (bug is in the test framework, not unikernel-specific)

Steps to reproduce

  • Run the namespace e2e test (currently only defined for Firecracker-unikraft in nerdctl):
make test_nerdctl_namespaces
  • The test passes — but it is falsely passing. To confirm it's a false positive, add a debug log inside the TimeNamespace case:
case specs.TimeNamespace:
    fmt.Printf("DEBUG: comparing uts=%s vs uts=%s (should be time!)\n",
        cntrNsMap["uts"], selfNsMap["uts"])
  • Re-run the test and observe the debug output — it prints UTS namespace inode numbers, not time namespace inode numbers, confirming the wrong namespace is being compared.

  • Expected behavior: The TimeNamespace case reads /proc//ns/time_for_children and compares the container's time namespace against the host's time namespace, validating that time namespace isolation is correctly applied.

  • Actual behavior: The TimeNamespace case re-reads /proc//ns/uts (same as the UTSNamespace case above) and silently passes, providing zero coverage for time namespace isolation.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions