From 0b0ce099a57cafa5127f58cb0a0a40ec8501e83c Mon Sep 17 00:00:00 2001 From: Yashika0724 Date: Sun, 25 Jan 2026 01:07:15 +0530 Subject: [PATCH 1/3] fix: add nil checks for all Linux spec dereferences Signed-off-by: Yashika0724 --- pkg/unikontainers/unikontainers.go | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/pkg/unikontainers/unikontainers.go b/pkg/unikontainers/unikontainers.go index 85dc1e2a..d7bca5fc 100644 --- a/pkg/unikontainers/unikontainers.go +++ b/pkg/unikontainers/unikontainers.go @@ -331,7 +331,11 @@ func (u *Unikontainer) Exec(metrics m.Writer) error { // Prepare Monitor rootfs // Make sure that rootfs is mounted with the correct propagation // flags so we can later pivot if needed. - err = prepareRoot(rootfsParams.MonRootfs, u.Spec.Linux.RootfsPropagation) + var rootfsPropagation string + if u.Spec.Linux != nil { + rootfsPropagation = u.Spec.Linux.RootfsPropagation + } + err = prepareRoot(rootfsParams.MonRootfs, rootfsPropagation) if err != nil { return err } @@ -454,11 +458,14 @@ func (u *Unikontainer) Exec(metrics m.Writer) error { vmmArgs.Command = unikernelCmd // pivot - _, err = findNS(u.Spec.Linux.Namespaces, specs.MountNamespace) - // We just want to check if a mount namespace was define din the list + // We just want to check if a mount namespace was defined in the list. // Therefore, if there was no error and the mount namespace was found - // we can pivot. - withPivot := err != nil + // we can pivot. If Linux spec is nil, assume no mount namespace defined. + withPivot := true + if u.Spec.Linux != nil { + _, err = findNS(u.Spec.Linux.Namespaces, specs.MountNamespace) + withPivot = err != nil + } err = changeRoot(rootfsParams.MonRootfs, withPivot) if err != nil { return err @@ -636,6 +643,9 @@ func (u *Unikontainer) Delete() error { // This function should be called only from a locked thread // (i.e. runtime. LockOSThread()) func (u Unikontainer) joinSandboxNetNs() error { + if u.Spec.Linux == nil { + return ErrNotExistingNS + } netNsPath, err := findNS(u.Spec.Linux.Namespaces, specs.NetworkNamespace) if err != nil && !errors.Is(err, ErrNotExistingNS) { return err @@ -825,6 +835,10 @@ func loadUnikontainerState(stateFilePath string) (*specs.State, error) { // The implementation is inspired from: // https://github.com/opencontainers/runc/blob/c8737446d2f99c1b7f2fcf374a7ee5b4519b2051/libcontainer/container_linux.go#L1047 func (u *Unikontainer) FormatNsenterInfo() (rdr io.Reader, retErr error) { + if u.Spec.Linux == nil { + return nil, fmt.Errorf("Linux spec is required for namespace configuration") + } + r := nl.NewNetlinkRequest(int(initMsg), 0) // Our custom messages cannot bubble up an error using returns, instead From baa67331e1b3156791f4a00d7ba23a6af8610ffe Mon Sep 17 00:00:00 2001 From: Yashika0724 Date: Tue, 27 Jan 2026 14:41:54 +0530 Subject: [PATCH 2/3] fix: add missing Exec nil checks Signed-off-by: Yashika0724 --- pkg/unikontainers/unikontainers.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/unikontainers/unikontainers.go b/pkg/unikontainers/unikontainers.go index d7bca5fc..f46f5df8 100644 --- a/pkg/unikontainers/unikontainers.go +++ b/pkg/unikontainers/unikontainers.go @@ -260,7 +260,7 @@ func (u *Unikontainer) Exec(metrics m.Writer) error { // ExecArgs // If memory limit is set in spec, use it instead of the config default value - if u.Spec.Linux.Resources.Memory != nil { + if u.Spec.Linux != nil && u.Spec.Linux.Resources != nil && u.Spec.Linux.Resources.Memory != nil { if u.Spec.Linux.Resources.Memory.Limit != nil { if *u.Spec.Linux.Resources.Memory.Limit > 0 { vmmArgs.MemSizeB = uint64(*u.Spec.Linux.Resources.Memory.Limit) // nolint:gosec @@ -270,7 +270,7 @@ func (u *Unikontainer) Exec(metrics m.Writer) error { // ExecArgs // Check if container is set to unconfined -- disable seccomp - if u.Spec.Linux.Seccomp == nil { + if u.Spec.Linux == nil || u.Spec.Linux.Seccomp == nil { uniklog.Warn("Seccomp is disabled") vmmArgs.Seccomp = false } From f260fc5ff0b00813e4cef0321c4ec59b815b8812 Mon Sep 17 00:00:00 2001 From: Yashika0724 Date: Sun, 1 Feb 2026 01:08:14 +0530 Subject: [PATCH 3/3] fix: validate Linux spec early during create Signed-off-by: Yashika0724 --- pkg/unikontainers/unikontainers.go | 30 ++++++++++-------------------- 1 file changed, 10 insertions(+), 20 deletions(-) diff --git a/pkg/unikontainers/unikontainers.go b/pkg/unikontainers/unikontainers.go index f46f5df8..44cc1360 100644 --- a/pkg/unikontainers/unikontainers.go +++ b/pkg/unikontainers/unikontainers.go @@ -71,6 +71,10 @@ func New(bundlePath string, containerID string, rootDir string, cfg *UruncConfig return nil, err } + if spec.Linux == nil { + return nil, fmt.Errorf("Linux platform is required for urunc containers") + } + containerName := spec.Annotations["io.kubernetes.cri.container-name"] if containerName == "queue-proxy" { uniklog.Warn("This is a queue-proxy container. Adding IP env.") @@ -260,7 +264,7 @@ func (u *Unikontainer) Exec(metrics m.Writer) error { // ExecArgs // If memory limit is set in spec, use it instead of the config default value - if u.Spec.Linux != nil && u.Spec.Linux.Resources != nil && u.Spec.Linux.Resources.Memory != nil { + if u.Spec.Linux.Resources != nil && u.Spec.Linux.Resources.Memory != nil { if u.Spec.Linux.Resources.Memory.Limit != nil { if *u.Spec.Linux.Resources.Memory.Limit > 0 { vmmArgs.MemSizeB = uint64(*u.Spec.Linux.Resources.Memory.Limit) // nolint:gosec @@ -270,7 +274,7 @@ func (u *Unikontainer) Exec(metrics m.Writer) error { // ExecArgs // Check if container is set to unconfined -- disable seccomp - if u.Spec.Linux == nil || u.Spec.Linux.Seccomp == nil { + if u.Spec.Linux.Seccomp == nil { uniklog.Warn("Seccomp is disabled") vmmArgs.Seccomp = false } @@ -331,11 +335,7 @@ func (u *Unikontainer) Exec(metrics m.Writer) error { // Prepare Monitor rootfs // Make sure that rootfs is mounted with the correct propagation // flags so we can later pivot if needed. - var rootfsPropagation string - if u.Spec.Linux != nil { - rootfsPropagation = u.Spec.Linux.RootfsPropagation - } - err = prepareRoot(rootfsParams.MonRootfs, rootfsPropagation) + err = prepareRoot(rootfsParams.MonRootfs, u.Spec.Linux.RootfsPropagation) if err != nil { return err } @@ -460,12 +460,9 @@ func (u *Unikontainer) Exec(metrics m.Writer) error { // pivot // We just want to check if a mount namespace was defined in the list. // Therefore, if there was no error and the mount namespace was found - // we can pivot. If Linux spec is nil, assume no mount namespace defined. - withPivot := true - if u.Spec.Linux != nil { - _, err = findNS(u.Spec.Linux.Namespaces, specs.MountNamespace) - withPivot = err != nil - } + // we can pivot. + _, err = findNS(u.Spec.Linux.Namespaces, specs.MountNamespace) + withPivot := err != nil err = changeRoot(rootfsParams.MonRootfs, withPivot) if err != nil { return err @@ -643,9 +640,6 @@ func (u *Unikontainer) Delete() error { // This function should be called only from a locked thread // (i.e. runtime. LockOSThread()) func (u Unikontainer) joinSandboxNetNs() error { - if u.Spec.Linux == nil { - return ErrNotExistingNS - } netNsPath, err := findNS(u.Spec.Linux.Namespaces, specs.NetworkNamespace) if err != nil && !errors.Is(err, ErrNotExistingNS) { return err @@ -835,10 +829,6 @@ func loadUnikontainerState(stateFilePath string) (*specs.State, error) { // The implementation is inspired from: // https://github.com/opencontainers/runc/blob/c8737446d2f99c1b7f2fcf374a7ee5b4519b2051/libcontainer/container_linux.go#L1047 func (u *Unikontainer) FormatNsenterInfo() (rdr io.Reader, retErr error) { - if u.Spec.Linux == nil { - return nil, fmt.Errorf("Linux spec is required for namespace configuration") - } - r := nl.NewNetlinkRequest(int(initMsg), 0) // Our custom messages cannot bubble up an error using returns, instead