Move SafeExec logic to internal safeexec package

Signed-off-by: Evan Lezar <elezar@nvidia.com>
This commit is contained in:
Evan Lezar 2025-02-28 14:38:02 +02:00
parent 715e09fbd4
commit 4088430fc1
No known key found for this signature in database
4 changed files with 49 additions and 8 deletions

View File

@ -27,6 +27,7 @@ import (
"github.com/NVIDIA/nvidia-container-toolkit/internal/config" "github.com/NVIDIA/nvidia-container-toolkit/internal/config"
"github.com/NVIDIA/nvidia-container-toolkit/internal/logger" "github.com/NVIDIA/nvidia-container-toolkit/internal/logger"
"github.com/NVIDIA/nvidia-container-toolkit/internal/oci" "github.com/NVIDIA/nvidia-container-toolkit/internal/oci"
safeexec "github.com/NVIDIA/nvidia-container-toolkit/internal/safe-exec"
) )
const ( const (
@ -39,6 +40,7 @@ const (
) )
type command struct { type command struct {
safeexec.Execer
logger logger.Interface logger logger.Interface
} }
@ -52,6 +54,7 @@ type options struct {
func NewCommand(logger logger.Interface) *cli.Command { func NewCommand(logger logger.Interface) *cli.Command {
c := command{ c := command{
logger: logger, logger: logger,
Execer: safeexec.New(logger),
} }
return c.build() return c.build()
} }
@ -141,7 +144,7 @@ func (m command) run(c *cli.Context, cfg *options) error {
args = append(args, folders...) args = append(args, folders...)
} }
return m.SafeExec(ldconfigPath, args, nil) return m.Exec(ldconfigPath, args, nil)
} }
// resolveLDConfigPath determines the LDConfig path to use for the system. // resolveLDConfigPath determines the LDConfig path to use for the system.

View File

@ -0,0 +1,37 @@
/**
# Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
**/
package safeexec
import "github.com/NVIDIA/nvidia-container-toolkit/internal/logger"
// An Execer implements an Exec function.
type Execer interface {
Exec(string, []string, []string) error
}
// A safeExecer is used to Exec an application from a memfd to prevent possible
// tampering.
type safeExecer struct {
logger logger.Interface
}
// New creates a safe Execer with the specified logger.
func New(logger logger.Interface) Execer {
return &safeExecer{
logger: logger,
}
}

View File

@ -14,7 +14,7 @@
# limitations under the License. # limitations under the License.
**/ **/
package ldcache package safeexec
import ( import (
"fmt" "fmt"
@ -25,11 +25,11 @@ import (
"github.com/opencontainers/runc/libcontainer/dmz" "github.com/opencontainers/runc/libcontainer/dmz"
) )
// SafeExec attempts to clone the specified binary (as an memfd, for example) before executing it. // Exec attempts to clone the specified binary (as an memfd, for example) before executing it.
func (m command) SafeExec(path string, args []string, envv []string) error { func (s *safeExecer) Exec(path string, args []string, envv []string) error {
safeExe, err := cloneBinary(path) safeExe, err := cloneBinary(path)
if err != nil { if err != nil {
m.logger.Warningf("Failed to clone binary %q: %v; falling back to Exec", path, err) s.logger.Warningf("Failed to clone binary %q: %v; falling back to Exec", path, err)
//nolint:gosec // TODO: Can we harden this so that there is less risk of command injection //nolint:gosec // TODO: Can we harden this so that there is less risk of command injection
return syscall.Exec(path, args, envv) return syscall.Exec(path, args, envv)
} }

View File

@ -17,13 +17,14 @@
# limitations under the License. # limitations under the License.
**/ **/
package ldcache package safeexec
import "syscall" import "syscall"
// SafeExec is not implemented on non-linux systems and forwards directly to the // Exec is not implemented on non-linux systems and forwards directly to the
// Exec syscall. // Exec syscall.
func (m *command) SafeExec(path string, args []string, envv []string) error { func (s *safeExecer) Exec(path string, args []string, envv []string) error {
s.logger.Warningf("Cloning binary not implemented for binary %q; falling back to Exec", path)
//nolint:gosec // TODO: Can we harden this so that there is less risk of command injection //nolint:gosec // TODO: Can we harden this so that there is less risk of command injection
return syscall.Exec(path, args, envv) return syscall.Exec(path, args, envv)
} }