2015-11-07 16:46:36 +00:00
|
|
|
// +build !windows
|
|
|
|
|
2014-07-10 22:11:35 +00:00
|
|
|
package execdriver
|
|
|
|
|
2014-07-10 22:31:01 +00:00
|
|
|
import (
|
2014-07-10 23:38:11 +00:00
|
|
|
"fmt"
|
2014-07-10 22:31:01 +00:00
|
|
|
"strings"
|
|
|
|
|
2015-03-29 21:17:23 +00:00
|
|
|
"github.com/docker/docker/pkg/stringutils"
|
2015-03-05 17:55:14 +00:00
|
|
|
"github.com/syndtr/gocapability/capability"
|
2014-07-10 22:31:01 +00:00
|
|
|
)
|
2014-07-10 22:11:35 +00:00
|
|
|
|
2015-05-08 16:40:05 +00:00
|
|
|
var capabilityList Capabilities
|
|
|
|
|
|
|
|
func init() {
|
|
|
|
last := capability.CAP_LAST_CAP
|
|
|
|
// hack for RHEL6 which has no /proc/sys/kernel/cap_last_cap
|
|
|
|
if last == capability.Cap(63) {
|
|
|
|
last = capability.CAP_BLOCK_SUSPEND
|
|
|
|
}
|
|
|
|
for _, cap := range capability.List() {
|
|
|
|
if cap > last {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
capabilityList = append(capabilityList,
|
|
|
|
&CapabilityMapping{
|
|
|
|
Key: strings.ToUpper(cap.String()),
|
|
|
|
Value: cap,
|
|
|
|
},
|
|
|
|
)
|
|
|
|
}
|
2015-03-05 17:55:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
type (
|
2015-07-28 00:43:22 +00:00
|
|
|
// CapabilityMapping maps linux capability name to its value of capability.Cap type
|
|
|
|
// Capabilities is one of the security systems in Linux Security Module (LSM)
|
|
|
|
// framework provided by the kernel.
|
|
|
|
// For more details on capabilities, see http://man7.org/linux/man-pages/man7/capabilities.7.html
|
2015-03-05 17:55:14 +00:00
|
|
|
CapabilityMapping struct {
|
|
|
|
Key string `json:"key,omitempty"`
|
|
|
|
Value capability.Cap `json:"value,omitempty"`
|
|
|
|
}
|
2015-07-28 00:43:22 +00:00
|
|
|
// Capabilities contains all CapabilityMapping
|
2015-03-05 17:55:14 +00:00
|
|
|
Capabilities []*CapabilityMapping
|
|
|
|
)
|
|
|
|
|
2015-07-28 00:43:22 +00:00
|
|
|
// String returns <key> of CapabilityMapping
|
2015-03-05 17:55:14 +00:00
|
|
|
func (c *CapabilityMapping) String() string {
|
|
|
|
return c.Key
|
|
|
|
}
|
|
|
|
|
2015-07-28 00:43:22 +00:00
|
|
|
// GetCapability returns CapabilityMapping which contains specific key
|
2015-03-05 17:55:14 +00:00
|
|
|
func GetCapability(key string) *CapabilityMapping {
|
|
|
|
for _, capp := range capabilityList {
|
|
|
|
if capp.Key == key {
|
|
|
|
cpy := *capp
|
|
|
|
return &cpy
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2015-07-28 00:43:22 +00:00
|
|
|
// GetAllCapabilities returns all of the capabilities
|
2015-03-05 17:55:14 +00:00
|
|
|
func GetAllCapabilities() []string {
|
|
|
|
output := make([]string, len(capabilityList))
|
|
|
|
for i, capability := range capabilityList {
|
|
|
|
output[i] = capability.String()
|
|
|
|
}
|
|
|
|
return output
|
|
|
|
}
|
|
|
|
|
2015-07-28 00:43:22 +00:00
|
|
|
// TweakCapabilities can tweak capabilities by adding or dropping capabilities
|
|
|
|
// based on the basics capabilities.
|
2014-07-10 23:38:11 +00:00
|
|
|
func TweakCapabilities(basics, adds, drops []string) ([]string, error) {
|
|
|
|
var (
|
|
|
|
newCaps []string
|
2015-03-05 17:55:14 +00:00
|
|
|
allCaps = GetAllCapabilities()
|
2014-07-10 23:38:11 +00:00
|
|
|
)
|
2014-07-10 23:02:39 +00:00
|
|
|
|
2014-07-10 23:38:11 +00:00
|
|
|
// look for invalid cap in the drop list
|
|
|
|
for _, cap := range drops {
|
|
|
|
if strings.ToLower(cap) == "all" {
|
|
|
|
continue
|
|
|
|
}
|
2015-03-29 21:17:23 +00:00
|
|
|
if !stringutils.InSlice(allCaps, cap) {
|
2014-07-16 19:14:26 +00:00
|
|
|
return nil, fmt.Errorf("Unknown capability drop: %q", cap)
|
2014-07-10 23:38:11 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// handle --cap-add=all
|
2015-03-29 21:17:23 +00:00
|
|
|
if stringutils.InSlice(adds, "all") {
|
2015-03-05 17:55:14 +00:00
|
|
|
basics = allCaps
|
2014-07-10 23:02:39 +00:00
|
|
|
}
|
|
|
|
|
2015-03-29 21:17:23 +00:00
|
|
|
if !stringutils.InSlice(drops, "all") {
|
2014-07-10 22:31:01 +00:00
|
|
|
for _, cap := range basics {
|
2015-08-07 22:24:18 +00:00
|
|
|
// skip `all` already handled above
|
2014-07-10 23:38:11 +00:00
|
|
|
if strings.ToLower(cap) == "all" {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
|
|
|
// if we don't drop `all`, add back all the non-dropped caps
|
2015-03-29 21:17:23 +00:00
|
|
|
if !stringutils.InSlice(drops, cap) {
|
2014-07-16 18:47:55 +00:00
|
|
|
newCaps = append(newCaps, strings.ToUpper(cap))
|
2014-07-10 22:31:01 +00:00
|
|
|
}
|
2014-07-10 22:11:35 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, cap := range adds {
|
2015-08-07 22:24:18 +00:00
|
|
|
// skip `all` already handled above
|
2014-07-10 22:31:01 +00:00
|
|
|
if strings.ToLower(cap) == "all" {
|
2014-07-10 23:02:39 +00:00
|
|
|
continue
|
2014-07-10 22:31:01 +00:00
|
|
|
}
|
2014-07-10 23:38:11 +00:00
|
|
|
|
2015-03-29 21:17:23 +00:00
|
|
|
if !stringutils.InSlice(allCaps, cap) {
|
2014-07-16 19:14:26 +00:00
|
|
|
return nil, fmt.Errorf("Unknown capability to add: %q", cap)
|
2014-07-10 23:38:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// add cap if not already in the list
|
2015-03-29 21:17:23 +00:00
|
|
|
if !stringutils.InSlice(newCaps, cap) {
|
2014-07-16 18:47:55 +00:00
|
|
|
newCaps = append(newCaps, strings.ToUpper(cap))
|
2014-07-10 22:11:35 +00:00
|
|
|
}
|
|
|
|
}
|
2014-07-10 23:38:11 +00:00
|
|
|
return newCaps, nil
|
2014-07-10 22:11:35 +00:00
|
|
|
}
|