bump syndtr/gocapability d98352740cb2c55f81556b63d4a1ec64c5a319c2

full diff: 2c00daeb6c...d98352740c

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This commit is contained in:
Sebastiaan van Stijn 2019-04-18 19:07:59 +02:00
parent 1962ec66bb
commit eeaa4e543a
No known key found for this signature in database
GPG Key ID: 76698F39D527CE8C
5 changed files with 140 additions and 32 deletions

View File

@ -70,7 +70,7 @@ github.com/shurcooL/sanitized_anchor_name 10ef21a441db47d8b13ebcc5fd23
github.com/sirupsen/logrus 8bdbc7bcc01dcbb8ec23dc8a28e332258d25251f # v1.4.1 github.com/sirupsen/logrus 8bdbc7bcc01dcbb8ec23dc8a28e332258d25251f # v1.4.1
github.com/spf13/cobra ef82de70bb3f60c65fb8eebacbb2d122ef517385 # v0.0.3 github.com/spf13/cobra ef82de70bb3f60c65fb8eebacbb2d122ef517385 # v0.0.3
github.com/spf13/pflag 4cb166e4f25ac4e8016a3595bbf7ea2e9aa85a2c https://github.com/thaJeztah/pflag.git # temporary fork with https://github.com/spf13/pflag/pull/170 applied, which isn't merged yet upstream github.com/spf13/pflag 4cb166e4f25ac4e8016a3595bbf7ea2e9aa85a2c https://github.com/thaJeztah/pflag.git # temporary fork with https://github.com/spf13/pflag/pull/170 applied, which isn't merged yet upstream
github.com/syndtr/gocapability 2c00daeb6c3b45114c80ac44119e7b8801fdd852 github.com/syndtr/gocapability d98352740cb2c55f81556b63d4a1ec64c5a319c2
github.com/theupdateframework/notary d6e1431feb32348e0650bf7551ac5cffd01d857b # v0.6.1 github.com/theupdateframework/notary d6e1431feb32348e0650bf7551ac5cffd01d857b # v0.6.1
github.com/tonistiigi/fsutil 3bbb99cdbd76619ab717299830c60f6f2a533a6b github.com/tonistiigi/fsutil 3bbb99cdbd76619ab717299830c60f6f2a533a6b
github.com/tonistiigi/units 6950e57a87eaf136bbe44ef2ec8e75b9e3569de2 github.com/tonistiigi/units 6950e57a87eaf136bbe44ef2ec8e75b9e3569de2

View File

@ -10,42 +10,42 @@ package capability
type Capabilities interface { type Capabilities interface {
// Get check whether a capability present in the given // Get check whether a capability present in the given
// capabilities set. The 'which' value should be one of EFFECTIVE, // capabilities set. The 'which' value should be one of EFFECTIVE,
// PERMITTED, INHERITABLE or BOUNDING. // PERMITTED, INHERITABLE, BOUNDING or AMBIENT.
Get(which CapType, what Cap) bool Get(which CapType, what Cap) bool
// Empty check whether all capability bits of the given capabilities // Empty check whether all capability bits of the given capabilities
// set are zero. The 'which' value should be one of EFFECTIVE, // set are zero. The 'which' value should be one of EFFECTIVE,
// PERMITTED, INHERITABLE or BOUNDING. // PERMITTED, INHERITABLE, BOUNDING or AMBIENT.
Empty(which CapType) bool Empty(which CapType) bool
// Full check whether all capability bits of the given capabilities // Full check whether all capability bits of the given capabilities
// set are one. The 'which' value should be one of EFFECTIVE, // set are one. The 'which' value should be one of EFFECTIVE,
// PERMITTED, INHERITABLE or BOUNDING. // PERMITTED, INHERITABLE, BOUNDING or AMBIENT.
Full(which CapType) bool Full(which CapType) bool
// Set sets capabilities of the given capabilities sets. The // Set sets capabilities of the given capabilities sets. The
// 'which' value should be one or combination (OR'ed) of EFFECTIVE, // 'which' value should be one or combination (OR'ed) of EFFECTIVE,
// PERMITTED, INHERITABLE or BOUNDING. // PERMITTED, INHERITABLE, BOUNDING or AMBIENT.
Set(which CapType, caps ...Cap) Set(which CapType, caps ...Cap)
// Unset unsets capabilities of the given capabilities sets. The // Unset unsets capabilities of the given capabilities sets. The
// 'which' value should be one or combination (OR'ed) of EFFECTIVE, // 'which' value should be one or combination (OR'ed) of EFFECTIVE,
// PERMITTED, INHERITABLE or BOUNDING. // PERMITTED, INHERITABLE, BOUNDING or AMBIENT.
Unset(which CapType, caps ...Cap) Unset(which CapType, caps ...Cap)
// Fill sets all bits of the given capabilities kind to one. The // Fill sets all bits of the given capabilities kind to one. The
// 'kind' value should be one or combination (OR'ed) of CAPS or // 'kind' value should be one or combination (OR'ed) of CAPS,
// BOUNDS. // BOUNDS or AMBS.
Fill(kind CapType) Fill(kind CapType)
// Clear sets all bits of the given capabilities kind to zero. The // Clear sets all bits of the given capabilities kind to zero. The
// 'kind' value should be one or combination (OR'ed) of CAPS or // 'kind' value should be one or combination (OR'ed) of CAPS,
// BOUNDS. // BOUNDS or AMBS.
Clear(kind CapType) Clear(kind CapType)
// String return current capabilities state of the given capabilities // String return current capabilities state of the given capabilities
// set as string. The 'which' value should be one of EFFECTIVE, // set as string. The 'which' value should be one of EFFECTIVE,
// PERMITTED, INHERITABLE or BOUNDING. // PERMITTED, INHERITABLE BOUNDING or AMBIENT
StringCap(which CapType) string StringCap(which CapType) string
// String return current capabilities state as string. // String return current capabilities state as string.
@ -60,13 +60,74 @@ type Capabilities interface {
Apply(kind CapType) error Apply(kind CapType) error
} }
// NewPid create new initialized Capabilities object for given pid when it // NewPid initializes a new Capabilities object for given pid when
// is nonzero, or for the current pid if pid is 0 // it is nonzero, or for the current process if pid is 0.
//
// Deprecated: Replace with NewPid2. For example, replace:
//
// c, err := NewPid(0)
// if err != nil {
// return err
// }
//
// with:
//
// c, err := NewPid2(0)
// if err != nil {
// return err
// }
// err = c.Load()
// if err != nil {
// return err
// }
func NewPid(pid int) (Capabilities, error) { func NewPid(pid int) (Capabilities, error) {
c, err := newPid(pid)
if err != nil {
return c, err
}
err = c.Load()
return c, err
}
// NewPid2 initializes a new Capabilities object for given pid when
// it is nonzero, or for the current process if pid is 0. This
// does not load the process's current capabilities; to do that you
// must call Load explicitly.
func NewPid2(pid int) (Capabilities, error) {
return newPid(pid) return newPid(pid)
} }
// NewFile create new initialized Capabilities object for given named file. // NewFile initializes a new Capabilities object for given file path.
func NewFile(name string) (Capabilities, error) { //
return newFile(name) // Deprecated: Replace with NewFile2. For example, replace:
//
// c, err := NewFile(path)
// if err != nil {
// return err
// }
//
// with:
//
// c, err := NewFile2(path)
// if err != nil {
// return err
// }
// err = c.Load()
// if err != nil {
// return err
// }
func NewFile(path string) (Capabilities, error) {
c, err := newFile(path)
if err != nil {
return c, err
}
err = c.Load()
return c, err
}
// NewFile2 creates a new initialized Capabilities object for given
// file path. This does not load the process's current capabilities;
// to do that you must call Load explicitly.
func NewFile2(path string) (Capabilities, error) {
return newFile(path)
} }

View File

@ -103,21 +103,17 @@ func newPid(pid int) (c Capabilities, err error) {
case linuxCapVer1: case linuxCapVer1:
p := new(capsV1) p := new(capsV1)
p.hdr.version = capVers p.hdr.version = capVers
p.hdr.pid = pid p.hdr.pid = int32(pid)
c = p c = p
case linuxCapVer2, linuxCapVer3: case linuxCapVer2, linuxCapVer3:
p := new(capsV3) p := new(capsV3)
p.hdr.version = capVers p.hdr.version = capVers
p.hdr.pid = pid p.hdr.pid = int32(pid)
c = p c = p
default: default:
err = errUnknownVers err = errUnknownVers
return return
} }
err = c.Load()
if err != nil {
c = nil
}
return return
} }
@ -238,6 +234,7 @@ type capsV3 struct {
hdr capHeader hdr capHeader
data [2]capData data [2]capData
bounds [2]uint32 bounds [2]uint32
ambient [2]uint32
} }
func (c *capsV3) Get(which CapType, what Cap) bool { func (c *capsV3) Get(which CapType, what Cap) bool {
@ -256,6 +253,8 @@ func (c *capsV3) Get(which CapType, what Cap) bool {
return (1<<uint(what))&c.data[i].inheritable != 0 return (1<<uint(what))&c.data[i].inheritable != 0
case BOUNDING: case BOUNDING:
return (1<<uint(what))&c.bounds[i] != 0 return (1<<uint(what))&c.bounds[i] != 0
case AMBIENT:
return (1<<uint(what))&c.ambient[i] != 0
} }
return false return false
@ -275,6 +274,9 @@ func (c *capsV3) getData(which CapType, dest []uint32) {
case BOUNDING: case BOUNDING:
dest[0] = c.bounds[0] dest[0] = c.bounds[0]
dest[1] = c.bounds[1] dest[1] = c.bounds[1]
case AMBIENT:
dest[0] = c.ambient[0]
dest[1] = c.ambient[1]
} }
} }
@ -313,6 +315,9 @@ func (c *capsV3) Set(which CapType, caps ...Cap) {
if which&BOUNDING != 0 { if which&BOUNDING != 0 {
c.bounds[i] |= 1 << uint(what) c.bounds[i] |= 1 << uint(what)
} }
if which&AMBIENT != 0 {
c.ambient[i] |= 1 << uint(what)
}
} }
} }
@ -336,6 +341,9 @@ func (c *capsV3) Unset(which CapType, caps ...Cap) {
if which&BOUNDING != 0 { if which&BOUNDING != 0 {
c.bounds[i] &= ^(1 << uint(what)) c.bounds[i] &= ^(1 << uint(what))
} }
if which&AMBIENT != 0 {
c.ambient[i] &= ^(1 << uint(what))
}
} }
} }
@ -353,6 +361,10 @@ func (c *capsV3) Fill(kind CapType) {
c.bounds[0] = 0xffffffff c.bounds[0] = 0xffffffff
c.bounds[1] = 0xffffffff c.bounds[1] = 0xffffffff
} }
if kind&AMBS == AMBS {
c.ambient[0] = 0xffffffff
c.ambient[1] = 0xffffffff
}
} }
func (c *capsV3) Clear(kind CapType) { func (c *capsV3) Clear(kind CapType) {
@ -369,6 +381,10 @@ func (c *capsV3) Clear(kind CapType) {
c.bounds[0] = 0 c.bounds[0] = 0
c.bounds[1] = 0 c.bounds[1] = 0
} }
if kind&AMBS == AMBS {
c.ambient[0] = 0
c.ambient[1] = 0
}
} }
func (c *capsV3) StringCap(which CapType) (ret string) { func (c *capsV3) StringCap(which CapType) (ret string) {
@ -408,7 +424,11 @@ func (c *capsV3) Load() (err error) {
} }
if strings.HasPrefix(line, "CapB") { if strings.HasPrefix(line, "CapB") {
fmt.Sscanf(line[4:], "nd: %08x%08x", &c.bounds[1], &c.bounds[0]) fmt.Sscanf(line[4:], "nd: %08x%08x", &c.bounds[1], &c.bounds[0])
break continue
}
if strings.HasPrefix(line, "CapA") {
fmt.Sscanf(line[4:], "mb: %08x%08x", &c.ambient[1], &c.ambient[0])
continue
} }
} }
f.Close() f.Close()
@ -442,7 +462,25 @@ func (c *capsV3) Apply(kind CapType) (err error) {
} }
if kind&CAPS == CAPS { if kind&CAPS == CAPS {
return capset(&c.hdr, &c.data[0]) err = capset(&c.hdr, &c.data[0])
if err != nil {
return
}
}
if kind&AMBS == AMBS {
for i := Cap(0); i <= CAP_LAST_CAP; i++ {
action := pr_CAP_AMBIENT_LOWER
if c.Get(AMBIENT, i) {
action = pr_CAP_AMBIENT_RAISE
}
err := prctl(pr_CAP_AMBIENT, action, uintptr(i), 0, 0)
// Ignore EINVAL as not supported on kernels before 4.3
if errno, ok := err.(syscall.Errno); ok && errno == syscall.EINVAL {
err = nil
continue
}
}
} }
return return
@ -450,10 +488,6 @@ func (c *capsV3) Apply(kind CapType) (err error) {
func newFile(path string) (c Capabilities, err error) { func newFile(path string) (c Capabilities, err error) {
c = &capsFile{path: path} c = &capsFile{path: path}
err = c.Load()
if err != nil {
c = nil
}
return return
} }

View File

@ -20,6 +20,8 @@ func (c CapType) String() string {
return "bounding" return "bounding"
case CAPS: case CAPS:
return "caps" return "caps"
case AMBIENT:
return "ambient"
} }
return "unknown" return "unknown"
} }
@ -29,9 +31,11 @@ const (
PERMITTED PERMITTED
INHERITABLE INHERITABLE
BOUNDING BOUNDING
AMBIENT
CAPS = EFFECTIVE | PERMITTED | INHERITABLE CAPS = EFFECTIVE | PERMITTED | INHERITABLE
BOUNDS = BOUNDING BOUNDS = BOUNDING
AMBS = AMBIENT
) )
//go:generate go run enumgen/gen.go //go:generate go run enumgen/gen.go

View File

@ -13,7 +13,7 @@ import (
type capHeader struct { type capHeader struct {
version uint32 version uint32
pid int pid int32
} }
type capData struct { type capData struct {
@ -38,6 +38,15 @@ func capset(hdr *capHeader, data *capData) (err error) {
return return
} }
// not yet in syscall
const (
pr_CAP_AMBIENT = 47
pr_CAP_AMBIENT_IS_SET = uintptr(1)
pr_CAP_AMBIENT_RAISE = uintptr(2)
pr_CAP_AMBIENT_LOWER = uintptr(3)
pr_CAP_AMBIENT_CLEAR_ALL = uintptr(4)
)
func prctl(option int, arg2, arg3, arg4, arg5 uintptr) (err error) { func prctl(option int, arg2, arg3, arg4, arg5 uintptr) (err error) {
_, _, e1 := syscall.Syscall6(syscall.SYS_PRCTL, uintptr(option), arg2, arg3, arg4, arg5, 0) _, _, e1 := syscall.Syscall6(syscall.SYS_PRCTL, uintptr(option), arg2, arg3, arg4, arg5, 0)
if e1 != 0 { if e1 != 0 {