Skip to content

bug: Kill aborts cleanup when OCI spec omits network namespace #1002

Description

@Nsanjayboruds

Description

Kill() aborts before reaching the VMM and network cleanup when the OCI specification does not contain a network namespace.

When linux.namespaces omits specs.NetworkNamespace, findNS() returns:

namespace network was not found

This error propagates through joinSandboxNetNs() to Kill(), which returns immediately instead of continuing with the VMM and network cleanup.

This means the cleanup path is skipped for this OCI configuration.

System info

  • urunc version/commit: b752cf9
  • Architecture: amd64
  • OS: Linux
  • Go: 1.26.4
  • VMM: Not exercised in the reproduction environment
  • Unikernel: Not exercised in the reproduction environment

Steps to reproduce

  1. Create an OCI specification whose linux.namespaces contains namespaces such as pid, ipc, uts, and mount, but omits the network namespace.
  2. Construct a Unikontainer using this OCI specification.
  3. Invoke Unikontainer.Kill().
  4. Observe the returned error and whether the cleanup functions are reached.

A minimal regression-style test reproduces the behavior:

=== RUN   TestKill_MissingNetworkNamespace
--- PASS: TestKill_MissingNetworkNamespace (0.00s)
PASS
ok      github.com/urunc-dev/urunc/pkg/unikontainers    0.003s

The test verifies that Kill() returns:

failed to join sandbox netns: namespace network was not found

and that the VMM stop function is not invoked.

Actual behavior

Kill() returns:

failed to join sandbox netns: namespace network was not found

before reaching the subsequent cleanup operations.

The relevant control flow is:

Kill()
  -> joinSandboxNetNs()
      -> findNS(..., specs.NetworkNamespace)
          -> namespace network was not found
  -> return error

Therefore the subsequent cleanup calls are not reached:

vmm.Stop(u.State.Pid)
network.CleanupAllUruncTaps()

The reproduction confirms:

Kill() return value: error
VMM.Stop() called: NO
Network cleanup called: NO

Expected behavior

If an OCI specification legitimately omits the network namespace, Kill() should still perform the required process/VMM cleanup instead of aborting before cleanup.

At minimum, absence of the namespace should not prevent the termination/cleanup path from being executed.

Root cause

findNS() returns an error when the requested namespace type is absent from the OCI namespace list:

namespace network was not found

joinSandboxNetNs() does not distinguish between an intentionally absent network namespace and other namespace lookup failures, so the error propagates to Kill().

Kill() then returns immediately and does not reach the VMM/network cleanup operations.

Testing

A temporary regression-style test was used to verify the behavior.

The test does not claim to demonstrate an actual orphaned QEMU/Firecracker process because a complete VMM/container lifecycle could not be exercised in the available environment.

The confirmed behavior is that Kill() returns before vmm.Stop() and network.CleanupAllUruncTaps() are invoked.

Relevance to robustness testing

This is an OCI edge case that can be exercised by structured testing/fuzzing by mutating the namespace configuration.

A robustness test suite should verify that lifecycle operations such as Kill() continue to perform required cleanup across valid and edge-case OCI configurations.

Possible fix direction

Investigate handling an absent network namespace separately from an invalid/unusable namespace.

The fix should avoid relying on matching an error string and should preserve genuinely fatal namespace errors.

A regression test should verify that a Unikontainer without a network namespace does not abort the cleanup path.

Related issues

I searched the existing urunc issues and pull requests for:

  • Kill
  • NetworkNamespace
  • network namespace
  • joinSandboxNetNs
  • namespace was not found
  • cleanup

Issue #240 is related to Kill() cleanup behavior but covers a different failure mode and does not address the missing network namespace case.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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