aboutsummaryrefslogtreecommitdiff
path: root/cap/file.go
diff options
context:
space:
mode:
Diffstat (limited to 'cap/file.go')
-rw-r--r--cap/file.go61
1 files changed, 34 insertions, 27 deletions
diff --git a/cap/file.go b/cap/file.go
index 70dae92..d92548f 100644
--- a/cap/file.go
+++ b/cap/file.go
@@ -50,7 +50,7 @@ type vfsCaps3 struct {
RootID uint32
}
-// ErrBadSize indicates the the loaded file capability has
+// ErrBadSize indicates the loaded file capability has
// an invalid number of bytes in it.
var ErrBadSize = errors.New("filecap bad size")
@@ -164,6 +164,8 @@ func (c *Set) GetNSOwner() (int, error) {
if magic < kv3 {
return 0, ErrBadMagic
}
+ c.mu.RLock()
+ defer c.mu.RUnlock()
return c.nsRoot, nil
}
@@ -187,6 +189,9 @@ func (c *Set) SetNSOwner(uid int) {
// attributes, the process is a little lossy with respect to effective
// bits.
func (c *Set) packFileCap() ([]byte, error) {
+ c.mu.RLock()
+ defer c.mu.RUnlock()
+
var magic uint32
switch words {
case 1:
@@ -229,20 +234,22 @@ func (c *Set) packFileCap() ([]byte, error) {
// (*os.File).Fd(). This function can also be used to delete a file's
// capabilities, by calling with c = nil.
//
-// Note, Linux does not store the full Effective Value Flag in the
-// metadata for the file. Only a single Effective bit is stored in
-// this metadata. This single bit is non-zero if the Effective vector
-// has any overlapping bits with the Permitted or Inheritable vector
-// of c. This may appear suboptimal, but the reasoning behind it is
-// sound. Namely, the purpose of the Effective bit it to support
-// capabability unaware binaries that will only work if they magically
-// launch with the needed bits already raised (this bit is sometimes
-// referred to simply as the 'legacy' bit). Without *full* support for
-// capability manipulation, as it is provided in this "../libcap/cap"
-// package, this was the only way for Go programs to make use of
+// Note, Linux does not store the full Effective Flag in the metadata
+// for the file. Only a single Effective bit is stored in this
+// metadata. This single bit is non-zero if the Effective Flag has any
+// overlapping bits with the Permitted or Inheritable Flags of c. This
+// may appear suboptimal, but the reasoning behind it is sound.
+// Namely, the purpose of the Effective bit it to support capabability
+// unaware binaries that will only work if they magically launch with
+// the needed Values already raised (this bit is sometimes referred to
+// simply as the 'legacy' bit).
+//
+// Historical note: without *full* support for runtime capability
+// manipulation, as it is provided in this "../libcap/cap" package,
+// this was previously the only way for Go programs to make use of
// file capabilities.
//
-// The preferred way a binary will actually manipulate its
+// The preferred way that a binary will actually manipulate its
// file-acquired capabilities is to carefully and deliberately use
// this package (or libcap, assisted by libpsx, for threaded C/C++
// family code).
@@ -253,8 +260,8 @@ func (c *Set) SetFd(file *os.File) error {
}
return nil
}
- c.mu.Lock()
- defer c.mu.Unlock()
+ c.mu.RLock()
+ defer c.mu.RUnlock()
d, err := c.packFileCap()
if err != nil {
return err
@@ -272,7 +279,7 @@ func (c *Set) SetFd(file *os.File) error {
// capabilities, by calling with c = nil.
//
// Note, see the comment for SetFd() for some non-obvious behavior of
-// Linux for the Effective Value vector on the modified file.
+// Linux for the Effective Flag on the modified file.
func (c *Set) SetFile(path string) error {
fi, err := os.Stat(path)
if err != nil {
@@ -295,8 +302,8 @@ func (c *Set) SetFile(path string) error {
}
return nil
}
- c.mu.Lock()
- defer c.mu.Unlock()
+ c.mu.RLock()
+ defer c.mu.RUnlock()
d, err := c.packFileCap()
if err != nil {
return err
@@ -348,11 +355,11 @@ func Import(d []byte) (*Set, error) {
return c, nil
}
-// To strictly match libcap, this value defaults to 8. Setting it to
-// zero can generate smaller external representations. Such smaller
-// representations can be imported by libcap and the Go package just
-// fine, we just default to the default libcap representation for
-// legacy reasons.
+// MinExtFlagSize defaults to 8 in order to be equivalent to libcap
+// defaults. Setting it to zero can generate smaller external
+// representations. Such smaller representations can be imported by
+// libcap and the Go package just fine, we just default to the default
+// libcap representation for legacy reasons.
var MinExtFlagSize = uint(8)
// Export exports a Set into a lossless byte array format where it is
@@ -362,16 +369,16 @@ var MinExtFlagSize = uint(8)
// Note, Export() generates exported byte streams that are importable
// by libcap.cap_copy_int() as well as Import().
func (c *Set) Export() ([]byte, error) {
- if c == nil {
- return nil, ErrBadSet
+ if err := c.good(); err != nil {
+ return nil, err
}
if MinExtFlagSize > 255 {
return nil, ErrOutOfRange
}
b := new(bytes.Buffer)
binary.Write(b, binary.LittleEndian, ExtMagic)
- c.mu.Lock()
- defer c.mu.Unlock()
+ c.mu.RLock()
+ defer c.mu.RUnlock()
var n = uint(0)
for i, f := range c.flat {
if nn := 4 * uint(i); nn+4 > n {