Browse code

bump syndtr/gocapability d98352740cb2c55f81556b63d4a1ec64c5a319c2

full diff: https://github.com/syndtr/gocapability/compare/2c00daeb6c3b45114c80ac44119e7b8801fdd852...d98352740cb2c55f81556b63d4a1ec64c5a319c2

relevant changes:

- syndtr/gocapability#11 Add support for ambient capabilities
- syndtr/gocapability#13 Fix issue #12: break too early
- syndtr/gocapability#16 Fix capHeader.pid type

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>

Sebastiaan van Stijn authored on 2019/04/14 06:03:42
Showing 5 changed files
... ...
@@ -89,7 +89,7 @@ github.com/seccomp/libseccomp-golang                32f571b70023028bd57d9288c20e
89 89
 # libcontainer deps (see src/github.com/opencontainers/runc/Godeps/Godeps.json)
90 90
 github.com/coreos/go-systemd                        39ca1b05acc7ad1220e09f133283b8859a8b71ab # v17
91 91
 github.com/godbus/dbus                              5f6efc7ef2759c81b7ba876593971bfce311eab3 # v4.0.0
92
-github.com/syndtr/gocapability                      2c00daeb6c3b45114c80ac44119e7b8801fdd852
92
+github.com/syndtr/gocapability                      d98352740cb2c55f81556b63d4a1ec64c5a319c2
93 93
 github.com/golang/protobuf                          aa810b61a9c79d51363740d207bb46cf8e620ed5 # v1.2.0
94 94
 
95 95
 # gelf logging driver deps
... ...
@@ -10,42 +10,42 @@ package capability
10 10
 type Capabilities interface {
11 11
 	// Get check whether a capability present in the given
12 12
 	// capabilities set. The 'which' value should be one of EFFECTIVE,
13
-	// PERMITTED, INHERITABLE or BOUNDING.
13
+	// PERMITTED, INHERITABLE, BOUNDING or AMBIENT.
14 14
 	Get(which CapType, what Cap) bool
15 15
 
16 16
 	// Empty check whether all capability bits of the given capabilities
17 17
 	// set are zero. The 'which' value should be one of EFFECTIVE,
18
-	// PERMITTED, INHERITABLE or BOUNDING.
18
+	// PERMITTED, INHERITABLE, BOUNDING or AMBIENT.
19 19
 	Empty(which CapType) bool
20 20
 
21 21
 	// Full check whether all capability bits of the given capabilities
22 22
 	// set are one. The 'which' value should be one of EFFECTIVE,
23
-	// PERMITTED, INHERITABLE or BOUNDING.
23
+	// PERMITTED, INHERITABLE, BOUNDING or AMBIENT.
24 24
 	Full(which CapType) bool
25 25
 
26 26
 	// Set sets capabilities of the given capabilities sets. The
27 27
 	// 'which' value should be one or combination (OR'ed) of EFFECTIVE,
28
-	// PERMITTED, INHERITABLE or BOUNDING.
28
+	// PERMITTED, INHERITABLE, BOUNDING or AMBIENT.
29 29
 	Set(which CapType, caps ...Cap)
30 30
 
31 31
 	// Unset unsets capabilities of the given capabilities sets. The
32 32
 	// 'which' value should be one or combination (OR'ed) of EFFECTIVE,
33
-	// PERMITTED, INHERITABLE or BOUNDING.
33
+	// PERMITTED, INHERITABLE, BOUNDING or AMBIENT.
34 34
 	Unset(which CapType, caps ...Cap)
35 35
 
36 36
 	// Fill sets all bits of the given capabilities kind to one. The
37
-	// 'kind' value should be one or combination (OR'ed) of CAPS or
38
-	// BOUNDS.
37
+	// 'kind' value should be one or combination (OR'ed) of CAPS,
38
+	// BOUNDS or AMBS.
39 39
 	Fill(kind CapType)
40 40
 
41 41
 	// Clear sets all bits of the given capabilities kind to zero. The
42
-	// 'kind' value should be one or combination (OR'ed) of CAPS or
43
-	// BOUNDS.
42
+	// 'kind' value should be one or combination (OR'ed) of CAPS,
43
+	// BOUNDS or AMBS.
44 44
 	Clear(kind CapType)
45 45
 
46 46
 	// String return current capabilities state of the given capabilities
47 47
 	// set as string. The 'which' value should be one of EFFECTIVE,
48
-	// PERMITTED, INHERITABLE or BOUNDING.
48
+	// PERMITTED, INHERITABLE BOUNDING or AMBIENT
49 49
 	StringCap(which CapType) string
50 50
 
51 51
 	// String return current capabilities state as string.
... ...
@@ -60,13 +60,74 @@ type Capabilities interface {
60 60
 	Apply(kind CapType) error
61 61
 }
62 62
 
63
-// NewPid create new initialized Capabilities object for given pid when it
64
-// is nonzero, or for the current pid if pid is 0
63
+// NewPid initializes a new Capabilities object for given pid when
64
+// it is nonzero, or for the current process if pid is 0.
65
+//
66
+// Deprecated: Replace with NewPid2.  For example, replace:
67
+//
68
+//    c, err := NewPid(0)
69
+//    if err != nil {
70
+//      return err
71
+//    }
72
+//
73
+// with:
74
+//
75
+//    c, err := NewPid2(0)
76
+//    if err != nil {
77
+//      return err
78
+//    }
79
+//    err = c.Load()
80
+//    if err != nil {
81
+//      return err
82
+//    }
65 83
 func NewPid(pid int) (Capabilities, error) {
84
+	c, err := newPid(pid)
85
+	if err != nil {
86
+		return c, err
87
+	}
88
+	err = c.Load()
89
+	return c, err
90
+}
91
+
92
+// NewPid2 initializes a new Capabilities object for given pid when
93
+// it is nonzero, or for the current process if pid is 0.  This
94
+// does not load the process's current capabilities; to do that you
95
+// must call Load explicitly.
96
+func NewPid2(pid int) (Capabilities, error) {
66 97
 	return newPid(pid)
67 98
 }
68 99
 
69
-// NewFile create new initialized Capabilities object for given named file.
70
-func NewFile(name string) (Capabilities, error) {
71
-	return newFile(name)
100
+// NewFile initializes a new Capabilities object for given file path.
101
+//
102
+// Deprecated: Replace with NewFile2.  For example, replace:
103
+//
104
+//    c, err := NewFile(path)
105
+//    if err != nil {
106
+//      return err
107
+//    }
108
+//
109
+// with:
110
+//
111
+//    c, err := NewFile2(path)
112
+//    if err != nil {
113
+//      return err
114
+//    }
115
+//    err = c.Load()
116
+//    if err != nil {
117
+//      return err
118
+//    }
119
+func NewFile(path string) (Capabilities, error) {
120
+	c, err := newFile(path)
121
+	if err != nil {
122
+		return c, err
123
+	}
124
+	err = c.Load()
125
+	return c, err
126
+}
127
+
128
+// NewFile2 creates a new initialized Capabilities object for given
129
+// file path.  This does not load the process's current capabilities;
130
+// to do that you must call Load explicitly.
131
+func NewFile2(path string) (Capabilities, error) {
132
+	return newFile(path)
72 133
 }
... ...
@@ -103,21 +103,17 @@ func newPid(pid int) (c Capabilities, err error) {
103 103
 	case linuxCapVer1:
104 104
 		p := new(capsV1)
105 105
 		p.hdr.version = capVers
106
-		p.hdr.pid = pid
106
+		p.hdr.pid = int32(pid)
107 107
 		c = p
108 108
 	case linuxCapVer2, linuxCapVer3:
109 109
 		p := new(capsV3)
110 110
 		p.hdr.version = capVers
111
-		p.hdr.pid = pid
111
+		p.hdr.pid = int32(pid)
112 112
 		c = p
113 113
 	default:
114 114
 		err = errUnknownVers
115 115
 		return
116 116
 	}
117
-	err = c.Load()
118
-	if err != nil {
119
-		c = nil
120
-	}
121 117
 	return
122 118
 }
123 119
 
... ...
@@ -235,9 +231,10 @@ func (c *capsV1) Apply(kind CapType) error {
235 235
 }
236 236
 
237 237
 type capsV3 struct {
238
-	hdr    capHeader
239
-	data   [2]capData
240
-	bounds [2]uint32
238
+	hdr     capHeader
239
+	data    [2]capData
240
+	bounds  [2]uint32
241
+	ambient [2]uint32
241 242
 }
242 243
 
243 244
 func (c *capsV3) Get(which CapType, what Cap) bool {
... ...
@@ -256,6 +253,8 @@ func (c *capsV3) Get(which CapType, what Cap) bool {
256 256
 		return (1<<uint(what))&c.data[i].inheritable != 0
257 257
 	case BOUNDING:
258 258
 		return (1<<uint(what))&c.bounds[i] != 0
259
+	case AMBIENT:
260
+		return (1<<uint(what))&c.ambient[i] != 0
259 261
 	}
260 262
 
261 263
 	return false
... ...
@@ -275,6 +274,9 @@ func (c *capsV3) getData(which CapType, dest []uint32) {
275 275
 	case BOUNDING:
276 276
 		dest[0] = c.bounds[0]
277 277
 		dest[1] = c.bounds[1]
278
+	case AMBIENT:
279
+		dest[0] = c.ambient[0]
280
+		dest[1] = c.ambient[1]
278 281
 	}
279 282
 }
280 283
 
... ...
@@ -313,6 +315,9 @@ func (c *capsV3) Set(which CapType, caps ...Cap) {
313 313
 		if which&BOUNDING != 0 {
314 314
 			c.bounds[i] |= 1 << uint(what)
315 315
 		}
316
+		if which&AMBIENT != 0 {
317
+			c.ambient[i] |= 1 << uint(what)
318
+		}
316 319
 	}
317 320
 }
318 321
 
... ...
@@ -336,6 +341,9 @@ func (c *capsV3) Unset(which CapType, caps ...Cap) {
336 336
 		if which&BOUNDING != 0 {
337 337
 			c.bounds[i] &= ^(1 << uint(what))
338 338
 		}
339
+		if which&AMBIENT != 0 {
340
+			c.ambient[i] &= ^(1 << uint(what))
341
+		}
339 342
 	}
340 343
 }
341 344
 
... ...
@@ -353,6 +361,10 @@ func (c *capsV3) Fill(kind CapType) {
353 353
 		c.bounds[0] = 0xffffffff
354 354
 		c.bounds[1] = 0xffffffff
355 355
 	}
356
+	if kind&AMBS == AMBS {
357
+		c.ambient[0] = 0xffffffff
358
+		c.ambient[1] = 0xffffffff
359
+	}
356 360
 }
357 361
 
358 362
 func (c *capsV3) Clear(kind CapType) {
... ...
@@ -369,6 +381,10 @@ func (c *capsV3) Clear(kind CapType) {
369 369
 		c.bounds[0] = 0
370 370
 		c.bounds[1] = 0
371 371
 	}
372
+	if kind&AMBS == AMBS {
373
+		c.ambient[0] = 0
374
+		c.ambient[1] = 0
375
+	}
372 376
 }
373 377
 
374 378
 func (c *capsV3) StringCap(which CapType) (ret string) {
... ...
@@ -408,7 +424,11 @@ func (c *capsV3) Load() (err error) {
408 408
 		}
409 409
 		if strings.HasPrefix(line, "CapB") {
410 410
 			fmt.Sscanf(line[4:], "nd:  %08x%08x", &c.bounds[1], &c.bounds[0])
411
-			break
411
+			continue
412
+		}
413
+		if strings.HasPrefix(line, "CapA") {
414
+			fmt.Sscanf(line[4:], "mb:  %08x%08x", &c.ambient[1], &c.ambient[0])
415
+			continue
412 416
 		}
413 417
 	}
414 418
 	f.Close()
... ...
@@ -442,7 +462,25 @@ func (c *capsV3) Apply(kind CapType) (err error) {
442 442
 	}
443 443
 
444 444
 	if kind&CAPS == CAPS {
445
-		return capset(&c.hdr, &c.data[0])
445
+		err = capset(&c.hdr, &c.data[0])
446
+		if err != nil {
447
+			return
448
+		}
449
+	}
450
+
451
+	if kind&AMBS == AMBS {
452
+		for i := Cap(0); i <= CAP_LAST_CAP; i++ {
453
+			action := pr_CAP_AMBIENT_LOWER
454
+			if c.Get(AMBIENT, i) {
455
+				action = pr_CAP_AMBIENT_RAISE
456
+			}
457
+			err := prctl(pr_CAP_AMBIENT, action, uintptr(i), 0, 0)
458
+			// Ignore EINVAL as not supported on kernels before 4.3
459
+			if errno, ok := err.(syscall.Errno); ok && errno == syscall.EINVAL {
460
+				err = nil
461
+				continue
462
+			}
463
+		}
446 464
 	}
447 465
 
448 466
 	return
... ...
@@ -450,10 +488,6 @@ func (c *capsV3) Apply(kind CapType) (err error) {
450 450
 
451 451
 func newFile(path string) (c Capabilities, err error) {
452 452
 	c = &capsFile{path: path}
453
-	err = c.Load()
454
-	if err != nil {
455
-		c = nil
456
-	}
457 453
 	return
458 454
 }
459 455
 
... ...
@@ -20,6 +20,8 @@ func (c CapType) String() string {
20 20
 		return "bounding"
21 21
 	case CAPS:
22 22
 		return "caps"
23
+	case AMBIENT:
24
+		return "ambient"
23 25
 	}
24 26
 	return "unknown"
25 27
 }
... ...
@@ -29,9 +31,11 @@ const (
29 29
 	PERMITTED
30 30
 	INHERITABLE
31 31
 	BOUNDING
32
+	AMBIENT
32 33
 
33 34
 	CAPS   = EFFECTIVE | PERMITTED | INHERITABLE
34 35
 	BOUNDS = BOUNDING
36
+	AMBS   = AMBIENT
35 37
 )
36 38
 
37 39
 //go:generate go run enumgen/gen.go
... ...
@@ -13,7 +13,7 @@ import (
13 13
 
14 14
 type capHeader struct {
15 15
 	version uint32
16
-	pid     int
16
+	pid     int32
17 17
 }
18 18
 
19 19
 type capData struct {
... ...
@@ -38,6 +38,15 @@ func capset(hdr *capHeader, data *capData) (err error) {
38 38
 	return
39 39
 }
40 40
 
41
+// not yet in syscall
42
+const (
43
+	pr_CAP_AMBIENT           = 47
44
+	pr_CAP_AMBIENT_IS_SET    = uintptr(1)
45
+	pr_CAP_AMBIENT_RAISE     = uintptr(2)
46
+	pr_CAP_AMBIENT_LOWER     = uintptr(3)
47
+	pr_CAP_AMBIENT_CLEAR_ALL = uintptr(4)
48
+)
49
+
41 50
 func prctl(option int, arg2, arg3, arg4, arg5 uintptr) (err error) {
42 51
 	_, _, e1 := syscall.Syscall6(syscall.SYS_PRCTL, uintptr(option), arg2, arg3, arg4, arg5, 0)
43 52
 	if e1 != 0 {