From 462c503a4762a0f20023d937a5fb05a55d4183a3 Mon Sep 17 00:00:00 2001 From: Daniel J Walsh Date: Fri, 17 Aug 2018 18:17:44 -0400 Subject: Fix handling of devices Devices are supposed to be able to be passed in via the form of --device /dev/foo --device /dev/foo:/dev/bar --device /dev/foo:rwm --device /dev/foo:/dev/bar:rwm Signed-off-by: Daniel J Walsh Closes: #1299 Approved by: umohnani8 --- pkg/spec/config_linux.go | 9 ++++++-- pkg/spec/parse.go | 55 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 62 insertions(+), 2 deletions(-) (limited to 'pkg/spec') diff --git a/pkg/spec/config_linux.go b/pkg/spec/config_linux.go index cd633bc69..ea04b95bd 100644 --- a/pkg/spec/config_linux.go +++ b/pkg/spec/config_linux.go @@ -28,10 +28,15 @@ func Device(d *configs.Device) spec.LinuxDevice { } func addDevice(g *generate.Generator, device string) error { - dev, err := devices.DeviceFromPath(device, "rwm") + src, dst, permissions, err := parseDevice(device) if err != nil { - return errors.Wrapf(err, "%s is not a valid device", device) + return err + } + dev, err := devices.DeviceFromPath(src, permissions) + if err != nil { + return errors.Wrapf(err, "%s is not a valid device", src) } + dev.Path = dst linuxdev := spec.LinuxDevice{ Path: dev.Path, Type: string(dev.Type), diff --git a/pkg/spec/parse.go b/pkg/spec/parse.go index d4a655e4f..d34e10760 100644 --- a/pkg/spec/parse.go +++ b/pkg/spec/parse.go @@ -126,3 +126,58 @@ func getLoggingPath(opts []string) string { } return "" } + +// parseDevice parses device mapping string to a src, dest & permissions string +func parseDevice(device string) (string, string, string, error) { //nolint + src := "" + dst := "" + permissions := "rwm" + arr := strings.Split(device, ":") + switch len(arr) { + case 3: + if !validDeviceMode(arr[2]) { + return "", "", "", fmt.Errorf("invalid device mode: %s", arr[2]) + } + permissions = arr[2] + fallthrough + case 2: + if validDeviceMode(arr[1]) { + permissions = arr[1] + } else { + if arr[1][0] != '/' { + return "", "", "", fmt.Errorf("invalid device mode: %s", arr[2]) + } + dst = arr[1] + } + fallthrough + case 1: + src = arr[0] + default: + return "", "", "", fmt.Errorf("invalid device specification: %s", device) + } + + if dst == "" { + dst = src + } + return src, dst, permissions, nil +} + +// validDeviceMode checks if the mode for device is valid or not. +// Valid mode is a composition of r (read), w (write), and m (mknod). +func validDeviceMode(mode string) bool { + var legalDeviceMode = map[rune]bool{ + 'r': true, + 'w': true, + 'm': true, + } + if mode == "" { + return false + } + for _, c := range mode { + if !legalDeviceMode[c] { + return false + } + legalDeviceMode[c] = false + } + return true +} -- cgit v1.2.3-54-g00ecf