Skip to content
This repository has been archived by the owner on Aug 12, 2021. It is now read-only.

Commit

Permalink
Add restrictions on the hyperkit binary
Browse files Browse the repository at this point in the history
If a hyperkit file exists in the same directory as the driver, than
that is the only binary allowed to be called.

In all cases the hyperkit binary must be either owned by root, or
have group ownership by wheel or admin.

Signed-off-by: Jan Dubois <jan.dubois@suse.com>
  • Loading branch information
jandubois committed Apr 27, 2021
1 parent 88d14fc commit 6c22fb0
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 11 deletions.
20 changes: 20 additions & 0 deletions cmd/priv/hyperkit.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import (
"encoding/json"
"fmt"
"os"
"path/filepath"
"syscall"

hyperkit "github.com/moby/hyperkit/go"
"github.com/rancher-sandbox/docker-machine-driver-hyperkit/cmd"
Expand Down Expand Up @@ -31,6 +33,24 @@ func Hyperkit() {
h.Disks = append(h.Disks, &disk)
}

// If a file called "hyperkit" exists in the same directory as the driver,
// then don't allow invoking any other binary.
executable := filepath.Join(cmd.DriverDir(), "hyperkit")
if _, err := os.Stat(executable); err == nil {
if h.HyperKit != executable {
cmd.Abort("Cannot invoke any other hyperkit executable than %s", executable)
}
}

// hyperkit executable must be owned by root (or group owned by either wheel or admin)
var stat syscall.Stat_t
if err := syscall.Stat(h.HyperKit, &stat); err != nil {
cmd.Abort("Cannot stat %s", h.HyperKit)
}
if stat.Uid != 0 && stat.Gid != 0 && stat.Gid != 80 {
cmd.Abort("Executable %s must be owned by root, or have group ownership by wheel(0) or admin(80)", h.HyperKit)
}

_, err = h.Start(os.Args[4])
if err != nil {
cmd.Abort("Failed to start hyperkit: %v", err)
Expand Down
20 changes: 18 additions & 2 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package cmd
import (
"fmt"
"os"
"path/filepath"
"strings"

"github.com/docker/machine/libmachine/log"
Expand Down Expand Up @@ -43,6 +44,11 @@ func onInit() {
}
}

func Execute() error {
return rootCmd.Execute()
}

// Abort prints the formatted error message to stdout and exits with a non-zero status.
func Abort(format string, args ...interface{}) {
msg := fmt.Sprintf(format, args...)
_, _ = os.Stderr.WriteString(msg)
Expand All @@ -52,6 +58,16 @@ func Abort(format string, args ...interface{}) {
os.Exit(1)
}

func Execute() error {
return rootCmd.Execute()
// DriverDir returns the absolute path to the directory containing the running executable
// after resolving symbolic links. Calls cmd.Abort() on failure; doesn't return an error.
func DriverDir() string {
executable, err := os.Executable()
if err != nil {
Abort("Cannot determine absolute path to current executable: %v", err)
}
executable, err = filepath.EvalSymlinks(executable)
if err != nil {
Abort("Cannot evaluate symlinks in path to current executable: %v", err)
}
return filepath.Dir(executable)
}
8 changes: 8 additions & 0 deletions cmd/start.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"encoding/json"
"fmt"
"path"
"path/filepath"
"strings"

"github.com/docker/machine/libmachine"
Expand Down Expand Up @@ -76,6 +77,13 @@ func newAPI() *libmachine.Client {
}

func newDriver(machineName, storePath string) (interface{}, error) {
if hyperkitPath != "" {
realPath, err := filepath.EvalSymlinks(hyperkitPath)
if err != nil {
Abort("Cannot evaluate symlinks in %s", hyperkitPath)
}
hyperkitPath = realPath
}
driver := hyperkit.Driver{
BaseDriver: &drivers.BaseDriver{
MachineName: machineName,
Expand Down
10 changes: 1 addition & 9 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,15 +68,7 @@ func main() {
// Add the directory name of the current executable to the front of the PATH to load
// the driver from the same directory (the current executable may be a symlink to the
// driver, living in a different directory).
executable, err := os.Executable()
if err != nil {
cmd.Abort("Cannot determine absolute path to current executable: %v", err)
}
executable, err = filepath.EvalSymlinks(executable)
if err != nil {
cmd.Abort("Cannot evaluate symlinks in path to current executable: %v", err)
}
err = os.Setenv("PATH", os.ExpandEnv(fmt.Sprintf("%s:$PATH", filepath.Dir(executable))))
err := os.Setenv("PATH", os.ExpandEnv(fmt.Sprintf("%s:$PATH", cmd.DriverDir())))
if err != nil {
cmd.Abort("Cannot update PATH: %v", err)
}
Expand Down

0 comments on commit 6c22fb0

Please sign in to comment.