Skip to content

A Go-based sandbox runner that limits CPU, memory, filesystem access, and execution time for spawned processes. Uses OS-level primitives (cgroups, job objects, namespaces where available) for safe local execution. Executes processes inside constrained sandboxes.

License

Notifications You must be signed in to change notification settings

BaseMax/go-proc-sandbox

Repository files navigation

go-proc-sandbox

A Go-based sandbox runner that limits CPU, memory, filesystem access, and execution time for spawned processes. Uses OS-level primitives (cgroups, job objects, namespaces where available) for safe local execution.

Features

  • Cross-platform: Supports Linux, Windows, and macOS/Unix systems
  • CPU Limiting: Control CPU usage percentage per process
  • Memory Limiting: Set maximum memory usage
  • Execution Timeout: Automatic termination after timeout
  • Process Limiting: Limit number of child processes
  • I/O Redirection: Capture stdout/stderr or provide stdin
  • Environment Control: Custom environment variables
  • Working Directory: Set custom working directory

Platform-Specific Implementation

Linux

  • Uses cgroups v2 for resource limiting (CPU, memory, process count)
  • Supports namespaces (mount, PID) for isolation
  • OOM killer detection for memory violations

Windows

  • Uses Job Objects for resource limiting
  • Memory and process count limits enforced
  • Automatic cleanup on job closure

macOS/Unix

  • Uses setrlimit for resource limiting
  • Process group management
  • Best-effort resource constraints

Installation

go get github.com/BaseMax/go-proc-sandbox

Quick Start

package main

import (
    "context"
    "fmt"
    "log"
    "time"

    "github.com/BaseMax/go-proc-sandbox"
)

func main() {
    // Create sandbox configuration
    config := &sandbox.Config{
        Timeout:     5 * time.Second,
        MemoryLimit: 100 * 1024 * 1024, // 100 MB
        CPULimit:    50,                 // 50% of one core
        MaxProcesses: 10,
    }

    // Create sandbox instance (auto-detects OS)
    sb, err := sandbox.New(config)
    if err != nil {
        log.Fatal(err)
    }
    defer sb.Cleanup()

    // Run a command
    result, err := sb.Run(context.Background(), "echo", "Hello, Sandbox!")
    if err != nil {
        log.Printf("Execution error: %v", err)
    }

    fmt.Printf("Exit Code: %d\n", result.ExitCode)
    fmt.Printf("Execution Time: %v\n", result.ExecutionTime)
    fmt.Printf("Timed Out: %v\n", result.TimedOut)
}

Configuration Options

type Config struct {
    // CPU limit in percentage (0-100 per core)
    CPULimit int

    // Memory limit in bytes
    MemoryLimit int64

    // Execution timeout
    Timeout time.Duration

    // Working directory for the process
    WorkingDir string

    // Allowed directories for read access
    AllowedDirs []string

    // Read-only directories
    ReadOnlyDirs []string

    // Environment variables
    Env []string

    // Stdin for the process
    Stdin io.Reader

    // Stdout for the process
    Stdout io.Writer

    // Stderr for the process
    Stderr io.Writer

    // NetworkAccess enables/disables network access
    NetworkAccess bool

    // MaxProcesses limits the number of processes
    MaxProcesses int
}

Usage Examples

Example 1: Timeout Handling

config := &sandbox.Config{
    Timeout: 2 * time.Second,
}

sb, _ := sandbox.New(config)
defer sb.Cleanup()

result, _ := sb.Run(context.Background(), "sleep", "10")
fmt.Printf("Timed Out: %v\n", result.TimedOut) // true

Example 2: Memory Limiting

config := &sandbox.Config{
    MemoryLimit: 50 * 1024 * 1024, // 50 MB
    Timeout:     10 * time.Second,
}

sb, _ := sandbox.New(config)
defer sb.Cleanup()

result, _ := sb.Run(context.Background(), "your-memory-intensive-app")
fmt.Printf("Memory Exceeded: %v\n", result.MemoryExceeded)

Example 3: I/O Redirection

var stdout, stderr bytes.Buffer

config := &sandbox.Config{
    Timeout: 5 * time.Second,
    Stdout:  &stdout,
    Stderr:  &stderr,
}

sb, _ := sandbox.New(config)
defer sb.Cleanup()

sb.Run(context.Background(), "echo", "output")
fmt.Printf("Output: %s\n", stdout.String())

Example 4: Custom Environment

config := &sandbox.Config{
    Timeout: 5 * time.Second,
    Env:     []string{"CUSTOM_VAR=value", "PATH=/usr/bin"},
}

sb, _ := sandbox.New(config)
defer sb.Cleanup()

sb.Run(context.Background(), "printenv", "CUSTOM_VAR")

Result Structure

type Result struct {
    // Exit code of the process
    ExitCode int

    // Execution time
    ExecutionTime time.Duration

    // Whether the process was killed due to timeout
    TimedOut bool

    // Whether the process exceeded memory limit
    MemoryExceeded bool

    // Error if any
    Error error
}

Running Examples

cd examples/basic
go run main.go

Running Tests

go test -v

Security Considerations

  • This library is designed for safe local execution, not as a container replacement
  • Root privileges may be required for full isolation on Linux (namespaces, cgroups)
  • Without root, the sandbox provides best-effort resource limiting
  • Always validate and sanitize command inputs
  • Be cautious with filesystem access and network settings

Limitations

Linux

  • Full cgroup v2 features require root or proper permissions
  • Namespace isolation requires appropriate capabilities
  • Some features may be limited in containerized environments

Windows

  • Job object features depend on Windows version
  • Some limits may not be enforced in all scenarios

macOS/Unix

  • Resource limits are best-effort using setrlimit
  • Less strict than Linux cgroups or Windows job objects
  • Memory limiting may not prevent all allocations

License

MIT License - see LICENSE file for details

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

Author

Copyright (c) 2024, Max Base

About

A Go-based sandbox runner that limits CPU, memory, filesystem access, and execution time for spawned processes. Uses OS-level primitives (cgroups, job objects, namespaces where available) for safe local execution. Executes processes inside constrained sandboxes.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages