Parcourir la source

vendor: github.com/opencontainers/selinux v1.9.1

full diff: https://github.com/opencontainers/selinux/compare/v1.8.2...v1.9.1

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Sebastiaan van Stijn il y a 3 ans
Parent
commit
615ff22437
24 fichiers modifiés avec 384 ajouts et 1529 suppressions
  1. 1 2
      vendor.conf
  2. 0 27
      vendor/github.com/bits-and-blooms/bitset/LICENSE
  3. 0 93
      vendor/github.com/bits-and-blooms/bitset/README.md
  4. 0 952
      vendor/github.com/bits-and-blooms/bitset/bitset.go
  5. 0 3
      vendor/github.com/bits-and-blooms/bitset/go.mod
  6. 0 53
      vendor/github.com/bits-and-blooms/bitset/popcnt.go
  7. 0 45
      vendor/github.com/bits-and-blooms/bitset/popcnt_19.go
  8. 0 68
      vendor/github.com/bits-and-blooms/bitset/popcnt_amd64.go
  9. 0 104
      vendor/github.com/bits-and-blooms/bitset/popcnt_amd64.s
  10. 0 24
      vendor/github.com/bits-and-blooms/bitset/popcnt_generic.go
  11. 0 14
      vendor/github.com/bits-and-blooms/bitset/trailing_zeros_18.go
  12. 0 9
      vendor/github.com/bits-and-blooms/bitset/trailing_zeros_19.go
  13. 8 5
      vendor/github.com/opencontainers/selinux/go-selinux/label/label_linux.go
  14. 22 0
      vendor/github.com/opencontainers/selinux/go-selinux/rchcon.go
  15. 21 0
      vendor/github.com/opencontainers/selinux/go-selinux/rchcon_go115.go
  16. 7 1
      vendor/github.com/opencontainers/selinux/go-selinux/selinux.go
  17. 126 115
      vendor/github.com/opencontainers/selinux/go-selinux/selinux_linux.go
  18. 4 2
      vendor/github.com/opencontainers/selinux/go-selinux/selinux_stub.go
  19. 2 2
      vendor/github.com/opencontainers/selinux/go-selinux/xattrs_linux.go
  20. 1 5
      vendor/github.com/opencontainers/selinux/go.mod
  21. 6 0
      vendor/github.com/opencontainers/selinux/pkg/pwalk/README.md
  22. 16 5
      vendor/github.com/opencontainers/selinux/pkg/pwalk/pwalk.go
  23. 54 0
      vendor/github.com/opencontainers/selinux/pkg/pwalkdir/README.md
  24. 116 0
      vendor/github.com/opencontainers/selinux/pkg/pwalkdir/pwalkdir.go

+ 1 - 2
vendor.conf

@@ -175,8 +175,7 @@ github.com/morikuni/aec                             39771216ff4c63d11f5e604076f9
 # metrics
 github.com/docker/go-metrics                        b619b3592b65de4f087d9f16863a7e6ff905973c # v0.0.1
 
-github.com/opencontainers/selinux                   76bc82e11d854d3e40c08889d13c98abcea72ea2 # v1.8.2
-github.com/bits-and-blooms/bitset                   59de210119f50cedaa42d175dc88b6335fcf63f6 # v1.2.0
+github.com/opencontainers/selinux                   95d3852f356b31cbb2d84040ffca303911d08273 # v1.9.1
 
 
 # archive/tar

+ 0 - 27
vendor/github.com/bits-and-blooms/bitset/LICENSE

@@ -1,27 +0,0 @@
-Copyright (c) 2014 Will Fitzgerald. All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-
-   * Redistributions of source code must retain the above copyright
-notice, this list of conditions and the following disclaimer.
-   * Redistributions in binary form must reproduce the above
-copyright notice, this list of conditions and the following disclaimer
-in the documentation and/or other materials provided with the
-distribution.
-   * Neither the name of Google Inc. nor the names of its
-contributors may be used to endorse or promote products derived from
-this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

+ 0 - 93
vendor/github.com/bits-and-blooms/bitset/README.md

@@ -1,93 +0,0 @@
-# bitset
-
-*Go language library to map between non-negative integers and boolean values*
-
-[![Test](https://github.com/bits-and-blooms/bitset/workflows/Test/badge.svg)](https://github.com/willf/bitset/actions?query=workflow%3ATest)
-[![Go Report Card](https://goreportcard.com/badge/github.com/willf/bitset)](https://goreportcard.com/report/github.com/willf/bitset)
-[![PkgGoDev](https://pkg.go.dev/badge/github.com/bits-and-blooms/bitset?tab=doc)](https://pkg.go.dev/github.com/bits-and-blooms/bitset?tab=doc)
-
-
-## Description
-
-Package bitset implements bitsets, a mapping between non-negative integers and boolean values.
-It should be more efficient than map[uint] bool.
-
-It provides methods for setting, clearing, flipping, and testing individual integers.
-
-But it also provides set intersection, union, difference, complement, and symmetric operations, as well as tests to check whether any, all, or no bits are set, and querying a bitset's current length and number of positive bits.
-
-BitSets are expanded to the size of the largest set bit; the memory allocation is approximately Max bits, where Max is the largest set bit. BitSets are never shrunk. On creation, a hint can be given for the number of bits that will be used.
-
-Many of the methods, including Set, Clear, and Flip, return a BitSet pointer, which allows for chaining.
-
-### Example use:
-
-```go
-package main
-
-import (
-	"fmt"
-	"math/rand"
-
-	"github.com/bits-and-blooms/bitset"
-)
-
-func main() {
-	fmt.Printf("Hello from BitSet!\n")
-	var b bitset.BitSet
-	// play some Go Fish
-	for i := 0; i < 100; i++ {
-		card1 := uint(rand.Intn(52))
-		card2 := uint(rand.Intn(52))
-		b.Set(card1)
-		if b.Test(card2) {
-			fmt.Println("Go Fish!")
-		}
-		b.Clear(card1)
-	}
-
-	// Chaining
-	b.Set(10).Set(11)
-
-	for i, e := b.NextSet(0); e; i, e = b.NextSet(i + 1) {
-		fmt.Println("The following bit is set:", i)
-	}
-	if b.Intersection(bitset.New(100).Set(10)).Count() == 1 {
-		fmt.Println("Intersection works.")
-	} else {
-		fmt.Println("Intersection doesn't work???")
-	}
-}
-```
-
-As an alternative to BitSets, one should check out the 'big' package, which provides a (less set-theoretical) view of bitsets.
-
-Package documentation is at: https://pkg.go.dev/github.com/bits-and-blooms/bitset?tab=doc
-
-## Memory Usage
-
-The memory usage of a bitset using N bits is at least N/8 bytes. The number of bits in a bitset is at least as large as one plus the greatest bit index you have accessed. Thus it is possible to run out of memory while using a bitset. If you have lots of bits, you might prefer compressed bitsets, like the [Roaring bitmaps](http://roaringbitmap.org) and its [Go implementation](https://github.com/RoaringBitmap/roaring).
-
-## Implementation Note
-
-Go 1.9 introduced a native `math/bits` library. We provide backward compatibility to Go 1.7, which might be removed.
-
-It is possible that a later version will match the `math/bits` return signature for counts (which is `int`, rather than our library's `unit64`). If so, the version will be bumped.
-
-## Installation
-
-```bash
-go get github.com/bits-and-blooms/bitset
-```
-
-## Contributing
-
-If you wish to contribute to this project, please branch and issue a pull request against master ("[GitHub Flow](https://guides.github.com/introduction/flow/)")
-
-## Running all tests
-
-Before committing the code, please check if it passes tests, has adequate coverage, etc.
-```bash
-go test
-go test -cover
-```

+ 0 - 952
vendor/github.com/bits-and-blooms/bitset/bitset.go

@@ -1,952 +0,0 @@
-/*
-Package bitset implements bitsets, a mapping
-between non-negative integers and boolean values. It should be more
-efficient than map[uint] bool.
-
-It provides methods for setting, clearing, flipping, and testing
-individual integers.
-
-But it also provides set intersection, union, difference,
-complement, and symmetric operations, as well as tests to
-check whether any, all, or no bits are set, and querying a
-bitset's current length and number of positive bits.
-
-BitSets are expanded to the size of the largest set bit; the
-memory allocation is approximately Max bits, where Max is
-the largest set bit. BitSets are never shrunk. On creation,
-a hint can be given for the number of bits that will be used.
-
-Many of the methods, including Set,Clear, and Flip, return
-a BitSet pointer, which allows for chaining.
-
-Example use:
-
-	import "bitset"
-	var b BitSet
-	b.Set(10).Set(11)
-	if b.Test(1000) {
-		b.Clear(1000)
-	}
-	if B.Intersection(bitset.New(100).Set(10)).Count() > 1 {
-		fmt.Println("Intersection works.")
-	}
-
-As an alternative to BitSets, one should check out the 'big' package,
-which provides a (less set-theoretical) view of bitsets.
-
-*/
-package bitset
-
-import (
-	"bufio"
-	"bytes"
-	"encoding/base64"
-	"encoding/binary"
-	"encoding/json"
-	"errors"
-	"fmt"
-	"io"
-	"strconv"
-)
-
-// the wordSize of a bit set
-const wordSize = uint(64)
-
-// log2WordSize is lg(wordSize)
-const log2WordSize = uint(6)
-
-// allBits has every bit set
-const allBits uint64 = 0xffffffffffffffff
-
-// default binary BigEndian
-var binaryOrder binary.ByteOrder = binary.BigEndian
-
-// default json encoding base64.URLEncoding
-var base64Encoding = base64.URLEncoding
-
-// Base64StdEncoding Marshal/Unmarshal BitSet with base64.StdEncoding(Default: base64.URLEncoding)
-func Base64StdEncoding() { base64Encoding = base64.StdEncoding }
-
-// LittleEndian Marshal/Unmarshal Binary as Little Endian(Default: binary.BigEndian)
-func LittleEndian() { binaryOrder = binary.LittleEndian }
-
-// A BitSet is a set of bits. The zero value of a BitSet is an empty set of length 0.
-type BitSet struct {
-	length uint
-	set    []uint64
-}
-
-// Error is used to distinguish errors (panics) generated in this package.
-type Error string
-
-// safeSet will fixup b.set to be non-nil and return the field value
-func (b *BitSet) safeSet() []uint64 {
-	if b.set == nil {
-		b.set = make([]uint64, wordsNeeded(0))
-	}
-	return b.set
-}
-
-// From is a constructor used to create a BitSet from an array of integers
-func From(buf []uint64) *BitSet {
-	return &BitSet{uint(len(buf)) * 64, buf}
-}
-
-// Bytes returns the bitset as array of integers
-func (b *BitSet) Bytes() []uint64 {
-	return b.set
-}
-
-// wordsNeeded calculates the number of words needed for i bits
-func wordsNeeded(i uint) int {
-	if i > (Cap() - wordSize + 1) {
-		return int(Cap() >> log2WordSize)
-	}
-	return int((i + (wordSize - 1)) >> log2WordSize)
-}
-
-// New creates a new BitSet with a hint that length bits will be required
-func New(length uint) (bset *BitSet) {
-	defer func() {
-		if r := recover(); r != nil {
-			bset = &BitSet{
-				0,
-				make([]uint64, 0),
-			}
-		}
-	}()
-
-	bset = &BitSet{
-		length,
-		make([]uint64, wordsNeeded(length)),
-	}
-
-	return bset
-}
-
-// Cap returns the total possible capacity, or number of bits
-func Cap() uint {
-	return ^uint(0)
-}
-
-// Len returns the number of bits in the BitSet.
-// Note the difference to method Count, see example.
-func (b *BitSet) Len() uint {
-	return b.length
-}
-
-// extendSetMaybe adds additional words to incorporate new bits if needed
-func (b *BitSet) extendSetMaybe(i uint) {
-	if i >= b.length { // if we need more bits, make 'em
-		if i >= Cap() {
-			panic("You are exceeding the capacity")
-		}
-		nsize := wordsNeeded(i + 1)
-		if b.set == nil {
-			b.set = make([]uint64, nsize)
-		} else if cap(b.set) >= nsize {
-			b.set = b.set[:nsize] // fast resize
-		} else if len(b.set) < nsize {
-			newset := make([]uint64, nsize, 2*nsize) // increase capacity 2x
-			copy(newset, b.set)
-			b.set = newset
-		}
-		b.length = i + 1
-	}
-}
-
-// Test whether bit i is set.
-func (b *BitSet) Test(i uint) bool {
-	if i >= b.length {
-		return false
-	}
-	return b.set[i>>log2WordSize]&(1<<(i&(wordSize-1))) != 0
-}
-
-// Set bit i to 1, the capacity of the bitset is automatically
-// increased accordingly.
-// If i>= Cap(), this function will panic.
-// Warning: using a very large value for 'i'
-// may lead to a memory shortage and a panic: the caller is responsible
-// for providing sensible parameters in line with their memory capacity.
-func (b *BitSet) Set(i uint) *BitSet {
-	b.extendSetMaybe(i)
-	b.set[i>>log2WordSize] |= 1 << (i & (wordSize - 1))
-	return b
-}
-
-// Clear bit i to 0
-func (b *BitSet) Clear(i uint) *BitSet {
-	if i >= b.length {
-		return b
-	}
-	b.set[i>>log2WordSize] &^= 1 << (i & (wordSize - 1))
-	return b
-}
-
-// SetTo sets bit i to value.
-// If i>= Cap(), this function will panic.
-// Warning: using a very large value for 'i'
-// may lead to a memory shortage and a panic: the caller is responsible
-// for providing sensible parameters in line with their memory capacity.
-func (b *BitSet) SetTo(i uint, value bool) *BitSet {
-	if value {
-		return b.Set(i)
-	}
-	return b.Clear(i)
-}
-
-// Flip bit at i.
-// If i>= Cap(), this function will panic.
-// Warning: using a very large value for 'i'
-// may lead to a memory shortage and a panic: the caller is responsible
-// for providing sensible parameters in line with their memory capacity.
-func (b *BitSet) Flip(i uint) *BitSet {
-	if i >= b.length {
-		return b.Set(i)
-	}
-	b.set[i>>log2WordSize] ^= 1 << (i & (wordSize - 1))
-	return b
-}
-
-// FlipRange bit in [start, end).
-// If end>= Cap(), this function will panic.
-// Warning: using a very large value for 'end'
-// may lead to a memory shortage and a panic: the caller is responsible
-// for providing sensible parameters in line with their memory capacity.
-func (b *BitSet) FlipRange(start, end uint) *BitSet {
-	if start >= end {
-		return b
-	}
-
-	b.extendSetMaybe(end - 1)
-	var startWord uint = start >> log2WordSize
-	var endWord uint = end >> log2WordSize
-	b.set[startWord] ^= ^(^uint64(0) << (start & (wordSize - 1)))
-	for i := startWord; i < endWord; i++ {
-		b.set[i] = ^b.set[i]
-	}
-	b.set[endWord] ^= ^uint64(0) >> (-end & (wordSize - 1))
-	return b
-}
-
-// Shrink shrinks BitSet so that the provided value is the last possible
-// set value. It clears all bits > the provided index and reduces the size
-// and length of the set.
-//
-// Note that the parameter value is not the new length in bits: it is the
-// maximal value that can be stored in the bitset after the function call.
-// The new length in bits is the parameter value + 1. Thus it is not possible
-// to use this function to set the length to 0, the minimal value of the length
-// after this function call is 1.
-//
-// A new slice is allocated to store the new bits, so you may see an increase in
-// memory usage until the GC runs. Normally this should not be a problem, but if you
-// have an extremely large BitSet its important to understand that the old BitSet will
-// remain in memory until the GC frees it.
-func (b *BitSet) Shrink(lastbitindex uint) *BitSet {
-	length := lastbitindex + 1
-	idx := wordsNeeded(length)
-	if idx > len(b.set) {
-		return b
-	}
-	shrunk := make([]uint64, idx)
-	copy(shrunk, b.set[:idx])
-	b.set = shrunk
-	b.length = length
-	b.set[idx-1] &= (allBits >> (uint64(64) - uint64(length&(wordSize-1))))
-	return b
-}
-
-// Compact shrinks BitSet to so that we preserve all set bits, while minimizing
-// memory usage. Compact calls Shrink.
-func (b *BitSet) Compact() *BitSet {
-	idx := len(b.set) - 1
-	for ; idx >= 0 && b.set[idx] == 0; idx-- {
-	}
-	newlength := uint((idx + 1) << log2WordSize)
-	if newlength >= b.length {
-		return b // nothing to do
-	}
-	if newlength > 0 {
-		return b.Shrink(newlength - 1)
-	}
-	// We preserve one word
-	return b.Shrink(63)
-}
-
-// InsertAt takes an index which indicates where a bit should be
-// inserted. Then it shifts all the bits in the set to the left by 1, starting
-// from the given index position, and sets the index position to 0.
-//
-// Depending on the size of your BitSet, and where you are inserting the new entry,
-// this method could be extremely slow and in some cases might cause the entire BitSet
-// to be recopied.
-func (b *BitSet) InsertAt(idx uint) *BitSet {
-	insertAtElement := (idx >> log2WordSize)
-
-	// if length of set is a multiple of wordSize we need to allocate more space first
-	if b.isLenExactMultiple() {
-		b.set = append(b.set, uint64(0))
-	}
-
-	var i uint
-	for i = uint(len(b.set) - 1); i > insertAtElement; i-- {
-		// all elements above the position where we want to insert can simply by shifted
-		b.set[i] <<= 1
-
-		// we take the most significant bit of the previous element and set it as
-		// the least significant bit of the current element
-		b.set[i] |= (b.set[i-1] & 0x8000000000000000) >> 63
-	}
-
-	// generate a mask to extract the data that we need to shift left
-	// within the element where we insert a bit
-	dataMask := ^(uint64(1)<<uint64(idx&(wordSize-1)) - 1)
-
-	// extract that data that we'll shift
-	data := b.set[i] & dataMask
-
-	// set the positions of the data mask to 0 in the element where we insert
-	b.set[i] &= ^dataMask
-
-	// shift data mask to the left and insert its data to the slice element
-	b.set[i] |= data << 1
-
-	// add 1 to length of BitSet
-	b.length++
-
-	return b
-}
-
-// String creates a string representation of the Bitmap
-func (b *BitSet) String() string {
-	// follows code from https://github.com/RoaringBitmap/roaring
-	var buffer bytes.Buffer
-	start := []byte("{")
-	buffer.Write(start)
-	counter := 0
-	i, e := b.NextSet(0)
-	for e {
-		counter = counter + 1
-		// to avoid exhausting the memory
-		if counter > 0x40000 {
-			buffer.WriteString("...")
-			break
-		}
-		buffer.WriteString(strconv.FormatInt(int64(i), 10))
-		i, e = b.NextSet(i + 1)
-		if e {
-			buffer.WriteString(",")
-		}
-	}
-	buffer.WriteString("}")
-	return buffer.String()
-}
-
-// DeleteAt deletes the bit at the given index position from
-// within the bitset
-// All the bits residing on the left of the deleted bit get
-// shifted right by 1
-// The running time of this operation may potentially be
-// relatively slow, O(length)
-func (b *BitSet) DeleteAt(i uint) *BitSet {
-	// the index of the slice element where we'll delete a bit
-	deleteAtElement := i >> log2WordSize
-
-	// generate a mask for the data that needs to be shifted right
-	// within that slice element that gets modified
-	dataMask := ^((uint64(1) << (i & (wordSize - 1))) - 1)
-
-	// extract the data that we'll shift right from the slice element
-	data := b.set[deleteAtElement] & dataMask
-
-	// set the masked area to 0 while leaving the rest as it is
-	b.set[deleteAtElement] &= ^dataMask
-
-	// shift the previously extracted data to the right and then
-	// set it in the previously masked area
-	b.set[deleteAtElement] |= (data >> 1) & dataMask
-
-	// loop over all the consecutive slice elements to copy each
-	// lowest bit into the highest position of the previous element,
-	// then shift the entire content to the right by 1
-	for i := int(deleteAtElement) + 1; i < len(b.set); i++ {
-		b.set[i-1] |= (b.set[i] & 1) << 63
-		b.set[i] >>= 1
-	}
-
-	b.length = b.length - 1
-
-	return b
-}
-
-// NextSet returns the next bit set from the specified index,
-// including possibly the current index
-// along with an error code (true = valid, false = no set bit found)
-// for i,e := v.NextSet(0); e; i,e = v.NextSet(i + 1) {...}
-//
-// Users concerned with performance may want to use NextSetMany to
-// retrieve several values at once.
-func (b *BitSet) NextSet(i uint) (uint, bool) {
-	x := int(i >> log2WordSize)
-	if x >= len(b.set) {
-		return 0, false
-	}
-	w := b.set[x]
-	w = w >> (i & (wordSize - 1))
-	if w != 0 {
-		return i + trailingZeroes64(w), true
-	}
-	x = x + 1
-	for x < len(b.set) {
-		if b.set[x] != 0 {
-			return uint(x)*wordSize + trailingZeroes64(b.set[x]), true
-		}
-		x = x + 1
-
-	}
-	return 0, false
-}
-
-// NextSetMany returns many next bit sets from the specified index,
-// including possibly the current index and up to cap(buffer).
-// If the returned slice has len zero, then no more set bits were found
-//
-//    buffer := make([]uint, 256) // this should be reused
-//    j := uint(0)
-//    j, buffer = bitmap.NextSetMany(j, buffer)
-//    for ; len(buffer) > 0; j, buffer = bitmap.NextSetMany(j,buffer) {
-//     for k := range buffer {
-//      do something with buffer[k]
-//     }
-//     j += 1
-//    }
-//
-//
-// It is possible to retrieve all set bits as follow:
-//
-//    indices := make([]uint, bitmap.Count())
-//    bitmap.NextSetMany(0, indices)
-//
-// However if bitmap.Count() is large, it might be preferable to
-// use several calls to NextSetMany, for performance reasons.
-func (b *BitSet) NextSetMany(i uint, buffer []uint) (uint, []uint) {
-	myanswer := buffer
-	capacity := cap(buffer)
-	x := int(i >> log2WordSize)
-	if x >= len(b.set) || capacity == 0 {
-		return 0, myanswer[:0]
-	}
-	skip := i & (wordSize - 1)
-	word := b.set[x] >> skip
-	myanswer = myanswer[:capacity]
-	size := int(0)
-	for word != 0 {
-		r := trailingZeroes64(word)
-		t := word & ((^word) + 1)
-		myanswer[size] = r + i
-		size++
-		if size == capacity {
-			goto End
-		}
-		word = word ^ t
-	}
-	x++
-	for idx, word := range b.set[x:] {
-		for word != 0 {
-			r := trailingZeroes64(word)
-			t := word & ((^word) + 1)
-			myanswer[size] = r + (uint(x+idx) << 6)
-			size++
-			if size == capacity {
-				goto End
-			}
-			word = word ^ t
-		}
-	}
-End:
-	if size > 0 {
-		return myanswer[size-1], myanswer[:size]
-	}
-	return 0, myanswer[:0]
-}
-
-// NextClear returns the next clear bit from the specified index,
-// including possibly the current index
-// along with an error code (true = valid, false = no bit found i.e. all bits are set)
-func (b *BitSet) NextClear(i uint) (uint, bool) {
-	x := int(i >> log2WordSize)
-	if x >= len(b.set) {
-		return 0, false
-	}
-	w := b.set[x]
-	w = w >> (i & (wordSize - 1))
-	wA := allBits >> (i & (wordSize - 1))
-	index := i + trailingZeroes64(^w)
-	if w != wA && index < b.length {
-		return index, true
-	}
-	x++
-	for x < len(b.set) {
-		index = uint(x)*wordSize + trailingZeroes64(^b.set[x])
-		if b.set[x] != allBits && index < b.length {
-			return index, true
-		}
-		x++
-	}
-	return 0, false
-}
-
-// ClearAll clears the entire BitSet
-func (b *BitSet) ClearAll() *BitSet {
-	if b != nil && b.set != nil {
-		for i := range b.set {
-			b.set[i] = 0
-		}
-	}
-	return b
-}
-
-// wordCount returns the number of words used in a bit set
-func (b *BitSet) wordCount() int {
-	return len(b.set)
-}
-
-// Clone this BitSet
-func (b *BitSet) Clone() *BitSet {
-	c := New(b.length)
-	if b.set != nil { // Clone should not modify current object
-		copy(c.set, b.set)
-	}
-	return c
-}
-
-// Copy into a destination BitSet
-// Returning the size of the destination BitSet
-// like array copy
-func (b *BitSet) Copy(c *BitSet) (count uint) {
-	if c == nil {
-		return
-	}
-	if b.set != nil { // Copy should not modify current object
-		copy(c.set, b.set)
-	}
-	count = c.length
-	if b.length < c.length {
-		count = b.length
-	}
-	return
-}
-
-// Count (number of set bits).
-// Also known as "popcount" or "population count".
-func (b *BitSet) Count() uint {
-	if b != nil && b.set != nil {
-		return uint(popcntSlice(b.set))
-	}
-	return 0
-}
-
-// Equal tests the equivalence of two BitSets.
-// False if they are of different sizes, otherwise true
-// only if all the same bits are set
-func (b *BitSet) Equal(c *BitSet) bool {
-	if c == nil || b == nil {
-		return c == b
-	}
-	if b.length != c.length {
-		return false
-	}
-	if b.length == 0 { // if they have both length == 0, then could have nil set
-		return true
-	}
-	// testing for equality shoud not transform the bitset (no call to safeSet)
-
-	for p, v := range b.set {
-		if c.set[p] != v {
-			return false
-		}
-	}
-	return true
-}
-
-func panicIfNull(b *BitSet) {
-	if b == nil {
-		panic(Error("BitSet must not be null"))
-	}
-}
-
-// Difference of base set and other set
-// This is the BitSet equivalent of &^ (and not)
-func (b *BitSet) Difference(compare *BitSet) (result *BitSet) {
-	panicIfNull(b)
-	panicIfNull(compare)
-	result = b.Clone() // clone b (in case b is bigger than compare)
-	l := int(compare.wordCount())
-	if l > int(b.wordCount()) {
-		l = int(b.wordCount())
-	}
-	for i := 0; i < l; i++ {
-		result.set[i] = b.set[i] &^ compare.set[i]
-	}
-	return
-}
-
-// DifferenceCardinality computes the cardinality of the differnce
-func (b *BitSet) DifferenceCardinality(compare *BitSet) uint {
-	panicIfNull(b)
-	panicIfNull(compare)
-	l := int(compare.wordCount())
-	if l > int(b.wordCount()) {
-		l = int(b.wordCount())
-	}
-	cnt := uint64(0)
-	cnt += popcntMaskSlice(b.set[:l], compare.set[:l])
-	cnt += popcntSlice(b.set[l:])
-	return uint(cnt)
-}
-
-// InPlaceDifference computes the difference of base set and other set
-// This is the BitSet equivalent of &^ (and not)
-func (b *BitSet) InPlaceDifference(compare *BitSet) {
-	panicIfNull(b)
-	panicIfNull(compare)
-	l := int(compare.wordCount())
-	if l > int(b.wordCount()) {
-		l = int(b.wordCount())
-	}
-	for i := 0; i < l; i++ {
-		b.set[i] &^= compare.set[i]
-	}
-}
-
-// Convenience function: return two bitsets ordered by
-// increasing length. Note: neither can be nil
-func sortByLength(a *BitSet, b *BitSet) (ap *BitSet, bp *BitSet) {
-	if a.length <= b.length {
-		ap, bp = a, b
-	} else {
-		ap, bp = b, a
-	}
-	return
-}
-
-// Intersection of base set and other set
-// This is the BitSet equivalent of & (and)
-func (b *BitSet) Intersection(compare *BitSet) (result *BitSet) {
-	panicIfNull(b)
-	panicIfNull(compare)
-	b, compare = sortByLength(b, compare)
-	result = New(b.length)
-	for i, word := range b.set {
-		result.set[i] = word & compare.set[i]
-	}
-	return
-}
-
-// IntersectionCardinality computes the cardinality of the union
-func (b *BitSet) IntersectionCardinality(compare *BitSet) uint {
-	panicIfNull(b)
-	panicIfNull(compare)
-	b, compare = sortByLength(b, compare)
-	cnt := popcntAndSlice(b.set, compare.set)
-	return uint(cnt)
-}
-
-// InPlaceIntersection destructively computes the intersection of
-// base set and the compare set.
-// This is the BitSet equivalent of & (and)
-func (b *BitSet) InPlaceIntersection(compare *BitSet) {
-	panicIfNull(b)
-	panicIfNull(compare)
-	l := int(compare.wordCount())
-	if l > int(b.wordCount()) {
-		l = int(b.wordCount())
-	}
-	for i := 0; i < l; i++ {
-		b.set[i] &= compare.set[i]
-	}
-	for i := l; i < len(b.set); i++ {
-		b.set[i] = 0
-	}
-	if compare.length > 0 {
-		b.extendSetMaybe(compare.length - 1)
-	}
-}
-
-// Union of base set and other set
-// This is the BitSet equivalent of | (or)
-func (b *BitSet) Union(compare *BitSet) (result *BitSet) {
-	panicIfNull(b)
-	panicIfNull(compare)
-	b, compare = sortByLength(b, compare)
-	result = compare.Clone()
-	for i, word := range b.set {
-		result.set[i] = word | compare.set[i]
-	}
-	return
-}
-
-// UnionCardinality computes the cardinality of the uniton of the base set
-// and the compare set.
-func (b *BitSet) UnionCardinality(compare *BitSet) uint {
-	panicIfNull(b)
-	panicIfNull(compare)
-	b, compare = sortByLength(b, compare)
-	cnt := popcntOrSlice(b.set, compare.set)
-	if len(compare.set) > len(b.set) {
-		cnt += popcntSlice(compare.set[len(b.set):])
-	}
-	return uint(cnt)
-}
-
-// InPlaceUnion creates the destructive union of base set and compare set.
-// This is the BitSet equivalent of | (or).
-func (b *BitSet) InPlaceUnion(compare *BitSet) {
-	panicIfNull(b)
-	panicIfNull(compare)
-	l := int(compare.wordCount())
-	if l > int(b.wordCount()) {
-		l = int(b.wordCount())
-	}
-	if compare.length > 0 {
-		b.extendSetMaybe(compare.length - 1)
-	}
-	for i := 0; i < l; i++ {
-		b.set[i] |= compare.set[i]
-	}
-	if len(compare.set) > l {
-		for i := l; i < len(compare.set); i++ {
-			b.set[i] = compare.set[i]
-		}
-	}
-}
-
-// SymmetricDifference of base set and other set
-// This is the BitSet equivalent of ^ (xor)
-func (b *BitSet) SymmetricDifference(compare *BitSet) (result *BitSet) {
-	panicIfNull(b)
-	panicIfNull(compare)
-	b, compare = sortByLength(b, compare)
-	// compare is bigger, so clone it
-	result = compare.Clone()
-	for i, word := range b.set {
-		result.set[i] = word ^ compare.set[i]
-	}
-	return
-}
-
-// SymmetricDifferenceCardinality computes the cardinality of the symmetric difference
-func (b *BitSet) SymmetricDifferenceCardinality(compare *BitSet) uint {
-	panicIfNull(b)
-	panicIfNull(compare)
-	b, compare = sortByLength(b, compare)
-	cnt := popcntXorSlice(b.set, compare.set)
-	if len(compare.set) > len(b.set) {
-		cnt += popcntSlice(compare.set[len(b.set):])
-	}
-	return uint(cnt)
-}
-
-// InPlaceSymmetricDifference creates the destructive SymmetricDifference of base set and other set
-// This is the BitSet equivalent of ^ (xor)
-func (b *BitSet) InPlaceSymmetricDifference(compare *BitSet) {
-	panicIfNull(b)
-	panicIfNull(compare)
-	l := int(compare.wordCount())
-	if l > int(b.wordCount()) {
-		l = int(b.wordCount())
-	}
-	if compare.length > 0 {
-		b.extendSetMaybe(compare.length - 1)
-	}
-	for i := 0; i < l; i++ {
-		b.set[i] ^= compare.set[i]
-	}
-	if len(compare.set) > l {
-		for i := l; i < len(compare.set); i++ {
-			b.set[i] = compare.set[i]
-		}
-	}
-}
-
-// Is the length an exact multiple of word sizes?
-func (b *BitSet) isLenExactMultiple() bool {
-	return b.length%wordSize == 0
-}
-
-// Clean last word by setting unused bits to 0
-func (b *BitSet) cleanLastWord() {
-	if !b.isLenExactMultiple() {
-		b.set[len(b.set)-1] &= allBits >> (wordSize - b.length%wordSize)
-	}
-}
-
-// Complement computes the (local) complement of a biset (up to length bits)
-func (b *BitSet) Complement() (result *BitSet) {
-	panicIfNull(b)
-	result = New(b.length)
-	for i, word := range b.set {
-		result.set[i] = ^word
-	}
-	result.cleanLastWord()
-	return
-}
-
-// All returns true if all bits are set, false otherwise. Returns true for
-// empty sets.
-func (b *BitSet) All() bool {
-	panicIfNull(b)
-	return b.Count() == b.length
-}
-
-// None returns true if no bit is set, false otherwise. Returns true for
-// empty sets.
-func (b *BitSet) None() bool {
-	panicIfNull(b)
-	if b != nil && b.set != nil {
-		for _, word := range b.set {
-			if word > 0 {
-				return false
-			}
-		}
-		return true
-	}
-	return true
-}
-
-// Any returns true if any bit is set, false otherwise
-func (b *BitSet) Any() bool {
-	panicIfNull(b)
-	return !b.None()
-}
-
-// IsSuperSet returns true if this is a superset of the other set
-func (b *BitSet) IsSuperSet(other *BitSet) bool {
-	for i, e := other.NextSet(0); e; i, e = other.NextSet(i + 1) {
-		if !b.Test(i) {
-			return false
-		}
-	}
-	return true
-}
-
-// IsStrictSuperSet returns true if this is a strict superset of the other set
-func (b *BitSet) IsStrictSuperSet(other *BitSet) bool {
-	return b.Count() > other.Count() && b.IsSuperSet(other)
-}
-
-// DumpAsBits dumps a bit set as a string of bits
-func (b *BitSet) DumpAsBits() string {
-	if b.set == nil {
-		return "."
-	}
-	buffer := bytes.NewBufferString("")
-	i := len(b.set) - 1
-	for ; i >= 0; i-- {
-		fmt.Fprintf(buffer, "%064b.", b.set[i])
-	}
-	return buffer.String()
-}
-
-// BinaryStorageSize returns the binary storage requirements
-func (b *BitSet) BinaryStorageSize() int {
-	return binary.Size(uint64(0)) + binary.Size(b.set)
-}
-
-// WriteTo writes a BitSet to a stream
-func (b *BitSet) WriteTo(stream io.Writer) (int64, error) {
-	length := uint64(b.length)
-
-	// Write length
-	err := binary.Write(stream, binaryOrder, length)
-	if err != nil {
-		return 0, err
-	}
-
-	// Write set
-	err = binary.Write(stream, binaryOrder, b.set)
-	return int64(b.BinaryStorageSize()), err
-}
-
-// ReadFrom reads a BitSet from a stream written using WriteTo
-func (b *BitSet) ReadFrom(stream io.Reader) (int64, error) {
-	var length uint64
-
-	// Read length first
-	err := binary.Read(stream, binaryOrder, &length)
-	if err != nil {
-		return 0, err
-	}
-	newset := New(uint(length))
-
-	if uint64(newset.length) != length {
-		return 0, errors.New("unmarshalling error: type mismatch")
-	}
-
-	// Read remaining bytes as set
-	err = binary.Read(stream, binaryOrder, newset.set)
-	if err != nil {
-		return 0, err
-	}
-
-	*b = *newset
-	return int64(b.BinaryStorageSize()), nil
-}
-
-// MarshalBinary encodes a BitSet into a binary form and returns the result.
-func (b *BitSet) MarshalBinary() ([]byte, error) {
-	var buf bytes.Buffer
-	writer := bufio.NewWriter(&buf)
-
-	_, err := b.WriteTo(writer)
-	if err != nil {
-		return []byte{}, err
-	}
-
-	err = writer.Flush()
-
-	return buf.Bytes(), err
-}
-
-// UnmarshalBinary decodes the binary form generated by MarshalBinary.
-func (b *BitSet) UnmarshalBinary(data []byte) error {
-	buf := bytes.NewReader(data)
-	reader := bufio.NewReader(buf)
-
-	_, err := b.ReadFrom(reader)
-
-	return err
-}
-
-// MarshalJSON marshals a BitSet as a JSON structure
-func (b *BitSet) MarshalJSON() ([]byte, error) {
-	buffer := bytes.NewBuffer(make([]byte, 0, b.BinaryStorageSize()))
-	_, err := b.WriteTo(buffer)
-	if err != nil {
-		return nil, err
-	}
-
-	// URLEncode all bytes
-	return json.Marshal(base64Encoding.EncodeToString(buffer.Bytes()))
-}
-
-// UnmarshalJSON unmarshals a BitSet from JSON created using MarshalJSON
-func (b *BitSet) UnmarshalJSON(data []byte) error {
-	// Unmarshal as string
-	var s string
-	err := json.Unmarshal(data, &s)
-	if err != nil {
-		return err
-	}
-
-	// URLDecode string
-	buf, err := base64Encoding.DecodeString(s)
-	if err != nil {
-		return err
-	}
-
-	_, err = b.ReadFrom(bytes.NewReader(buf))
-	return err
-}

+ 0 - 3
vendor/github.com/bits-and-blooms/bitset/go.mod

@@ -1,3 +0,0 @@
-module github.com/bits-and-blooms/bitset
-
-go 1.14

+ 0 - 53
vendor/github.com/bits-and-blooms/bitset/popcnt.go

@@ -1,53 +0,0 @@
-package bitset
-
-// bit population count, take from
-// https://code.google.com/p/go/issues/detail?id=4988#c11
-// credit: https://code.google.com/u/arnehormann/
-func popcount(x uint64) (n uint64) {
-	x -= (x >> 1) & 0x5555555555555555
-	x = (x>>2)&0x3333333333333333 + x&0x3333333333333333
-	x += x >> 4
-	x &= 0x0f0f0f0f0f0f0f0f
-	x *= 0x0101010101010101
-	return x >> 56
-}
-
-func popcntSliceGo(s []uint64) uint64 {
-	cnt := uint64(0)
-	for _, x := range s {
-		cnt += popcount(x)
-	}
-	return cnt
-}
-
-func popcntMaskSliceGo(s, m []uint64) uint64 {
-	cnt := uint64(0)
-	for i := range s {
-		cnt += popcount(s[i] &^ m[i])
-	}
-	return cnt
-}
-
-func popcntAndSliceGo(s, m []uint64) uint64 {
-	cnt := uint64(0)
-	for i := range s {
-		cnt += popcount(s[i] & m[i])
-	}
-	return cnt
-}
-
-func popcntOrSliceGo(s, m []uint64) uint64 {
-	cnt := uint64(0)
-	for i := range s {
-		cnt += popcount(s[i] | m[i])
-	}
-	return cnt
-}
-
-func popcntXorSliceGo(s, m []uint64) uint64 {
-	cnt := uint64(0)
-	for i := range s {
-		cnt += popcount(s[i] ^ m[i])
-	}
-	return cnt
-}

+ 0 - 45
vendor/github.com/bits-and-blooms/bitset/popcnt_19.go

@@ -1,45 +0,0 @@
-// +build go1.9
-
-package bitset
-
-import "math/bits"
-
-func popcntSlice(s []uint64) uint64 {
-	var cnt int
-	for _, x := range s {
-		cnt += bits.OnesCount64(x)
-	}
-	return uint64(cnt)
-}
-
-func popcntMaskSlice(s, m []uint64) uint64 {
-	var cnt int
-	for i := range s {
-		cnt += bits.OnesCount64(s[i] &^ m[i])
-	}
-	return uint64(cnt)
-}
-
-func popcntAndSlice(s, m []uint64) uint64 {
-	var cnt int
-	for i := range s {
-		cnt += bits.OnesCount64(s[i] & m[i])
-	}
-	return uint64(cnt)
-}
-
-func popcntOrSlice(s, m []uint64) uint64 {
-	var cnt int
-	for i := range s {
-		cnt += bits.OnesCount64(s[i] | m[i])
-	}
-	return uint64(cnt)
-}
-
-func popcntXorSlice(s, m []uint64) uint64 {
-	var cnt int
-	for i := range s {
-		cnt += bits.OnesCount64(s[i] ^ m[i])
-	}
-	return uint64(cnt)
-}

+ 0 - 68
vendor/github.com/bits-and-blooms/bitset/popcnt_amd64.go

@@ -1,68 +0,0 @@
-// +build !go1.9
-// +build amd64,!appengine
-
-package bitset
-
-// *** the following functions are defined in popcnt_amd64.s
-
-//go:noescape
-
-func hasAsm() bool
-
-// useAsm is a flag used to select the GO or ASM implementation of the popcnt function
-var useAsm = hasAsm()
-
-//go:noescape
-
-func popcntSliceAsm(s []uint64) uint64
-
-//go:noescape
-
-func popcntMaskSliceAsm(s, m []uint64) uint64
-
-//go:noescape
-
-func popcntAndSliceAsm(s, m []uint64) uint64
-
-//go:noescape
-
-func popcntOrSliceAsm(s, m []uint64) uint64
-
-//go:noescape
-
-func popcntXorSliceAsm(s, m []uint64) uint64
-
-func popcntSlice(s []uint64) uint64 {
-	if useAsm {
-		return popcntSliceAsm(s)
-	}
-	return popcntSliceGo(s)
-}
-
-func popcntMaskSlice(s, m []uint64) uint64 {
-	if useAsm {
-		return popcntMaskSliceAsm(s, m)
-	}
-	return popcntMaskSliceGo(s, m)
-}
-
-func popcntAndSlice(s, m []uint64) uint64 {
-	if useAsm {
-		return popcntAndSliceAsm(s, m)
-	}
-	return popcntAndSliceGo(s, m)
-}
-
-func popcntOrSlice(s, m []uint64) uint64 {
-	if useAsm {
-		return popcntOrSliceAsm(s, m)
-	}
-	return popcntOrSliceGo(s, m)
-}
-
-func popcntXorSlice(s, m []uint64) uint64 {
-	if useAsm {
-		return popcntXorSliceAsm(s, m)
-	}
-	return popcntXorSliceGo(s, m)
-}

+ 0 - 104
vendor/github.com/bits-and-blooms/bitset/popcnt_amd64.s

@@ -1,104 +0,0 @@
-// +build !go1.9
-// +build amd64,!appengine
-
-TEXT ·hasAsm(SB),4,$0-1
-MOVQ $1, AX
-CPUID
-SHRQ $23, CX
-ANDQ $1, CX
-MOVB CX, ret+0(FP)
-RET
-
-#define POPCNTQ_DX_DX BYTE $0xf3; BYTE $0x48; BYTE $0x0f; BYTE $0xb8; BYTE $0xd2
-
-TEXT ·popcntSliceAsm(SB),4,$0-32
-XORQ	AX, AX
-MOVQ	s+0(FP), SI
-MOVQ	s_len+8(FP), CX
-TESTQ	CX, CX
-JZ		popcntSliceEnd
-popcntSliceLoop:
-BYTE $0xf3; BYTE $0x48; BYTE $0x0f; BYTE $0xb8; BYTE $0x16 // POPCNTQ (SI), DX
-ADDQ	DX, AX
-ADDQ	$8, SI
-LOOP	popcntSliceLoop
-popcntSliceEnd:
-MOVQ	AX, ret+24(FP)
-RET
-
-TEXT ·popcntMaskSliceAsm(SB),4,$0-56
-XORQ	AX, AX
-MOVQ	s+0(FP), SI
-MOVQ	s_len+8(FP), CX
-TESTQ	CX, CX
-JZ		popcntMaskSliceEnd
-MOVQ	m+24(FP), DI
-popcntMaskSliceLoop:
-MOVQ	(DI), DX
-NOTQ	DX
-ANDQ	(SI), DX
-POPCNTQ_DX_DX
-ADDQ	DX, AX
-ADDQ	$8, SI
-ADDQ	$8, DI
-LOOP	popcntMaskSliceLoop
-popcntMaskSliceEnd:
-MOVQ	AX, ret+48(FP)
-RET
-
-TEXT ·popcntAndSliceAsm(SB),4,$0-56
-XORQ	AX, AX
-MOVQ	s+0(FP), SI
-MOVQ	s_len+8(FP), CX
-TESTQ	CX, CX
-JZ		popcntAndSliceEnd
-MOVQ	m+24(FP), DI
-popcntAndSliceLoop:
-MOVQ	(DI), DX
-ANDQ	(SI), DX
-POPCNTQ_DX_DX
-ADDQ	DX, AX
-ADDQ	$8, SI
-ADDQ	$8, DI
-LOOP	popcntAndSliceLoop
-popcntAndSliceEnd:
-MOVQ	AX, ret+48(FP)
-RET
-
-TEXT ·popcntOrSliceAsm(SB),4,$0-56
-XORQ	AX, AX
-MOVQ	s+0(FP), SI
-MOVQ	s_len+8(FP), CX
-TESTQ	CX, CX
-JZ		popcntOrSliceEnd
-MOVQ	m+24(FP), DI
-popcntOrSliceLoop:
-MOVQ	(DI), DX
-ORQ		(SI), DX
-POPCNTQ_DX_DX
-ADDQ	DX, AX
-ADDQ	$8, SI
-ADDQ	$8, DI
-LOOP	popcntOrSliceLoop
-popcntOrSliceEnd:
-MOVQ	AX, ret+48(FP)
-RET
-
-TEXT ·popcntXorSliceAsm(SB),4,$0-56
-XORQ	AX, AX
-MOVQ	s+0(FP), SI
-MOVQ	s_len+8(FP), CX
-TESTQ	CX, CX
-JZ		popcntXorSliceEnd
-MOVQ	m+24(FP), DI
-popcntXorSliceLoop:
-MOVQ	(DI), DX
-XORQ	(SI), DX
-POPCNTQ_DX_DX
-ADDQ	DX, AX
-ADDQ	$8, SI
-ADDQ	$8, DI
-LOOP	popcntXorSliceLoop
-popcntXorSliceEnd:
-MOVQ	AX, ret+48(FP)
-RET

+ 0 - 24
vendor/github.com/bits-and-blooms/bitset/popcnt_generic.go

@@ -1,24 +0,0 @@
-// +build !go1.9
-// +build !amd64 appengine
-
-package bitset
-
-func popcntSlice(s []uint64) uint64 {
-	return popcntSliceGo(s)
-}
-
-func popcntMaskSlice(s, m []uint64) uint64 {
-	return popcntMaskSliceGo(s, m)
-}
-
-func popcntAndSlice(s, m []uint64) uint64 {
-	return popcntAndSliceGo(s, m)
-}
-
-func popcntOrSlice(s, m []uint64) uint64 {
-	return popcntOrSliceGo(s, m)
-}
-
-func popcntXorSlice(s, m []uint64) uint64 {
-	return popcntXorSliceGo(s, m)
-}

+ 0 - 14
vendor/github.com/bits-and-blooms/bitset/trailing_zeros_18.go

@@ -1,14 +0,0 @@
-// +build !go1.9
-
-package bitset
-
-var deBruijn = [...]byte{
-	0, 1, 56, 2, 57, 49, 28, 3, 61, 58, 42, 50, 38, 29, 17, 4,
-	62, 47, 59, 36, 45, 43, 51, 22, 53, 39, 33, 30, 24, 18, 12, 5,
-	63, 55, 48, 27, 60, 41, 37, 16, 46, 35, 44, 21, 52, 32, 23, 11,
-	54, 26, 40, 15, 34, 20, 31, 10, 25, 14, 19, 9, 13, 8, 7, 6,
-}
-
-func trailingZeroes64(v uint64) uint {
-	return uint(deBruijn[((v&-v)*0x03f79d71b4ca8b09)>>58])
-}

+ 0 - 9
vendor/github.com/bits-and-blooms/bitset/trailing_zeros_19.go

@@ -1,9 +0,0 @@
-// +build go1.9
-
-package bitset
-
-import "math/bits"
-
-func trailingZeroes64(v uint64) uint {
-	return uint(bits.TrailingZeros64(v))
-}

+ 8 - 5
vendor/github.com/opencontainers/selinux/go-selinux/label/label_linux.go

@@ -1,12 +1,13 @@
 package label
 
 import (
+	"errors"
+	"fmt"
 	"os"
 	"os/user"
 	"strings"
 
 	"github.com/opencontainers/selinux/go-selinux"
-	"github.com/pkg/errors"
 )
 
 // Valid Label Options
@@ -53,11 +54,11 @@ func InitLabels(options []string) (plabel string, mlabel string, retErr error) {
 				return "", selinux.PrivContainerMountLabel(), nil
 			}
 			if i := strings.Index(opt, ":"); i == -1 {
-				return "", "", errors.Errorf("Bad label option %q, valid options 'disable' or \n'user, role, level, type, filetype' followed by ':' and a value", opt)
+				return "", "", fmt.Errorf("Bad label option %q, valid options 'disable' or \n'user, role, level, type, filetype' followed by ':' and a value", opt)
 			}
 			con := strings.SplitN(opt, ":", 2)
 			if !validOptions[con[0]] {
-				return "", "", errors.Errorf("Bad label option %q, valid options 'disable, user, role, level, type, filetype'", con[0])
+				return "", "", fmt.Errorf("Bad label option %q, valid options 'disable, user, role, level, type, filetype'", con[0])
 			}
 			if con[0] == "filetype" {
 				mcon["type"] = con[1]
@@ -102,9 +103,11 @@ func SetFileCreateLabel(fileLabel string) error {
 	return selinux.SetFSCreateLabel(fileLabel)
 }
 
-// Relabel changes the label of path to the filelabel string.
+// Relabel changes the label of path and all the entries beneath the path.
 // It changes the MCS label to s0 if shared is true.
 // This will allow all containers to share the content.
+//
+// The path itself is guaranteed to be relabeled last.
 func Relabel(path string, fileLabel string, shared bool) error {
 	if !selinux.GetEnabled() || fileLabel == "" {
 		return nil
@@ -151,7 +154,7 @@ func Relabel(path string, fileLabel string, shared bool) error {
 		path = strings.TrimSuffix(path, "/")
 	}
 	if exclude_paths[path] {
-		return errors.Errorf("SELinux relabeling of %s is not allowed", path)
+		return fmt.Errorf("SELinux relabeling of %s is not allowed", path)
 	}
 
 	if shared {

+ 22 - 0
vendor/github.com/opencontainers/selinux/go-selinux/rchcon.go

@@ -0,0 +1,22 @@
+// +build linux,go1.16
+
+package selinux
+
+import (
+	"errors"
+	"io/fs"
+	"os"
+
+	"github.com/opencontainers/selinux/pkg/pwalkdir"
+)
+
+func rchcon(fpath, label string) error {
+	return pwalkdir.Walk(fpath, func(p string, _ fs.DirEntry, _ error) error {
+		e := setFileLabel(p, label)
+		// Walk a file tree can race with removal, so ignore ENOENT.
+		if errors.Is(e, os.ErrNotExist) {
+			return nil
+		}
+		return e
+	})
+}

+ 21 - 0
vendor/github.com/opencontainers/selinux/go-selinux/rchcon_go115.go

@@ -0,0 +1,21 @@
+// +build linux,!go1.16
+
+package selinux
+
+import (
+	"errors"
+	"os"
+
+	"github.com/opencontainers/selinux/pkg/pwalk"
+)
+
+func rchcon(fpath, label string) error {
+	return pwalk.Walk(fpath, func(p string, _ os.FileInfo, _ error) error {
+		e := setFileLabel(p, label)
+		// Walk a file tree can race with removal, so ignore ENOENT.
+		if errors.Is(e, os.ErrNotExist) {
+			return nil
+		}
+		return e
+	})
+}

+ 7 - 1
vendor/github.com/opencontainers/selinux/go-selinux/selinux.go

@@ -1,7 +1,7 @@
 package selinux
 
 import (
-	"github.com/pkg/errors"
+	"errors"
 )
 
 const (
@@ -38,6 +38,8 @@ var (
 
 	// CategoryRange allows the upper bound on the category range to be adjusted
 	CategoryRange = DefaultCategoryRange
+
+	privContainerMountLabel string
 )
 
 // Context is a representation of the SELinux label broken into 4 parts
@@ -253,6 +255,8 @@ func CopyLevel(src, dest string) (string, error) {
 // Chcon changes the fpath file object to the SELinux label label.
 // If fpath is a directory and recurse is true, then Chcon walks the
 // directory tree setting the label.
+//
+// The fpath itself is guaranteed to be relabeled last.
 func Chcon(fpath string, label string, recurse bool) error {
 	return chcon(fpath, label, recurse)
 }
@@ -280,5 +284,7 @@ func GetDefaultContextWithLevel(user, level, scon string) (string, error) {
 
 // PrivContainerMountLabel returns mount label for privileged containers
 func PrivContainerMountLabel() string {
+	// Make sure label is initialized.
+	_ = label("")
 	return privContainerMountLabel
 }

+ 126 - 115
vendor/github.com/opencontainers/selinux/go-selinux/selinux_linux.go

@@ -5,20 +5,18 @@ import (
 	"bytes"
 	"crypto/rand"
 	"encoding/binary"
+	"errors"
 	"fmt"
 	"io"
 	"io/ioutil"
+	"math/big"
 	"os"
 	"path"
 	"path/filepath"
-	"regexp"
 	"strconv"
 	"strings"
 	"sync"
 
-	"github.com/bits-and-blooms/bitset"
-	"github.com/opencontainers/selinux/pkg/pwalk"
-	"github.com/pkg/errors"
 	"golang.org/x/sys/unix"
 )
 
@@ -35,8 +33,6 @@ const (
 	xattrNameSelinux = "security.selinux"
 )
 
-var policyRoot = filepath.Join(selinuxDir, readConfig(selinuxTypeTag))
-
 type selinuxState struct {
 	enabledSet    bool
 	enabled       bool
@@ -48,7 +44,7 @@ type selinuxState struct {
 
 type level struct {
 	sens uint
-	cats *bitset.BitSet
+	cats *big.Int
 }
 
 type mlsRange struct {
@@ -71,7 +67,6 @@ const (
 )
 
 var (
-	assignRegex       = regexp.MustCompile(`^([^=]+)=(.*)$`)
 	readOnlyFileLabel string
 	state             = selinuxState{
 		mcsList: make(map[string]bool),
@@ -80,8 +75,24 @@ var (
 	// for attrPath()
 	attrPathOnce   sync.Once
 	haveThreadSelf bool
+
+	// for policyRoot()
+	policyRootOnce sync.Once
+	policyRootVal  string
+
+	// for label()
+	loadLabelsOnce sync.Once
+	labels         map[string]string
 )
 
+func policyRoot() string {
+	policyRootOnce.Do(func() {
+		policyRootVal = filepath.Join(selinuxDir, readConfig(selinuxTypeTag))
+	})
+
+	return policyRootVal
+}
+
 func (s *selinuxState) setEnable(enabled bool) bool {
 	s.Lock()
 	defer s.Unlock()
@@ -120,7 +131,7 @@ func verifySELinuxfsMount(mnt string) bool {
 		if err == nil {
 			break
 		}
-		if err == unix.EAGAIN || err == unix.EINTR {
+		if err == unix.EAGAIN || err == unix.EINTR { //nolint:errorlint // unix errors are bare
 			continue
 		}
 		return false
@@ -223,7 +234,7 @@ func readConfig(target string) string {
 	scanner := bufio.NewScanner(in)
 
 	for scanner.Scan() {
-		line := strings.TrimSpace(scanner.Text())
+		line := bytes.TrimSpace(scanner.Bytes())
 		if len(line) == 0 {
 			// Skip blank lines
 			continue
@@ -232,11 +243,12 @@ func readConfig(target string) string {
 			// Skip comments
 			continue
 		}
-		if groups := assignRegex.FindStringSubmatch(line); groups != nil {
-			key, val := strings.TrimSpace(groups[1]), strings.TrimSpace(groups[2])
-			if key == target {
-				return strings.Trim(val, "\"")
-			}
+		fields := bytes.SplitN(line, []byte{'='}, 2)
+		if len(fields) != 2 {
+			continue
+		}
+		if bytes.Equal(fields[0], []byte(target)) {
+			return string(bytes.Trim(fields[1], `"`))
 		}
 	}
 	return ""
@@ -250,12 +262,12 @@ func isProcHandle(fh *os.File) error {
 		if err == nil {
 			break
 		}
-		if err != unix.EINTR {
-			return errors.Wrapf(err, "statfs(%q) failed", fh.Name())
+		if err != unix.EINTR { //nolint:errorlint // unix errors are bare
+			return &os.PathError{Op: "fstatfs", Path: fh.Name(), Err: err}
 		}
 	}
 	if buf.Type != unix.PROC_SUPER_MAGIC {
-		return errors.Errorf("file %q is not on procfs", fh.Name())
+		return fmt.Errorf("file %q is not on procfs", fh.Name())
 	}
 
 	return nil
@@ -275,12 +287,15 @@ func readCon(fpath string) (string, error) {
 	if err := isProcHandle(in); err != nil {
 		return "", err
 	}
+	return readConFd(in)
+}
 
-	var retval string
-	if _, err := fmt.Fscanf(in, "%s", &retval); err != nil {
+func readConFd(in *os.File) (string, error) {
+	data, err := ioutil.ReadAll(in)
+	if err != nil {
 		return "", err
 	}
-	return strings.Trim(retval, "\x00"), nil
+	return string(bytes.TrimSuffix(data, []byte{0})), nil
 }
 
 // classIndex returns the int index for an object class in the loaded policy,
@@ -311,8 +326,8 @@ func setFileLabel(fpath string, label string) error {
 		if err == nil {
 			break
 		}
-		if err != unix.EINTR {
-			return errors.Wrapf(err, "failed to set file label on %s", fpath)
+		if err != unix.EINTR { //nolint:errorlint // unix errors are bare
+			return &os.PathError{Op: "lsetxattr", Path: fpath, Err: err}
 		}
 	}
 
@@ -327,7 +342,7 @@ func fileLabel(fpath string) (string, error) {
 
 	label, err := lgetxattr(fpath, xattrNameSelinux)
 	if err != nil {
-		return "", err
+		return "", &os.PathError{Op: "lgetxattr", Path: fpath, Err: err}
 	}
 	// Trim the NUL byte at the end of the byte buffer, if present.
 	if len(label) > 0 && label[len(label)-1] == '\x00' {
@@ -390,7 +405,7 @@ func writeCon(fpath, val string) error {
 		_, err = out.Write(nil)
 	}
 	if err != nil {
-		return errors.Wrapf(err, "failed to set %s on procfs", fpath)
+		return err
 	}
 	return nil
 }
@@ -440,8 +455,8 @@ func computeCreateContext(source string, target string, class string) (string, e
 }
 
 // catsToBitset stores categories in a bitset.
-func catsToBitset(cats string) (*bitset.BitSet, error) {
-	bitset := &bitset.BitSet{}
+func catsToBitset(cats string) (*big.Int, error) {
+	bitset := new(big.Int)
 
 	catlist := strings.Split(cats, ",")
 	for _, r := range catlist {
@@ -456,14 +471,14 @@ func catsToBitset(cats string) (*bitset.BitSet, error) {
 				return nil, err
 			}
 			for i := catstart; i <= catend; i++ {
-				bitset.Set(i)
+				bitset.SetBit(bitset, int(i), 1)
 			}
 		} else {
 			cat, err := parseLevelItem(ranges[0], category)
 			if err != nil {
 				return nil, err
 			}
-			bitset.Set(cat)
+			bitset.SetBit(bitset, int(cat), 1)
 		}
 	}
 
@@ -489,13 +504,13 @@ func (l *level) parseLevel(levelStr string) error {
 	lvl := strings.SplitN(levelStr, ":", 2)
 	sens, err := parseLevelItem(lvl[0], sensitivity)
 	if err != nil {
-		return errors.Wrap(err, "failed to parse sensitivity")
+		return fmt.Errorf("failed to parse sensitivity: %w", err)
 	}
 	l.sens = sens
 	if len(lvl) > 1 {
 		cats, err := catsToBitset(lvl[1])
 		if err != nil {
-			return errors.Wrap(err, "failed to parse categories")
+			return fmt.Errorf("failed to parse categories: %w", err)
 		}
 		l.cats = cats
 	}
@@ -513,14 +528,14 @@ func rangeStrToMLSRange(rangeStr string) (*mlsRange, error) {
 	case 2:
 		mlsRange.high = &level{}
 		if err := mlsRange.high.parseLevel(levelSlice[1]); err != nil {
-			return nil, errors.Wrapf(err, "failed to parse high level %q", levelSlice[1])
+			return nil, fmt.Errorf("failed to parse high level %q: %w", levelSlice[1], err)
 		}
 		fallthrough
 	// rangeStr that is single level, e.g. s6:c0,c3,c5,c30.c1023
 	case 1:
 		mlsRange.low = &level{}
 		if err := mlsRange.low.parseLevel(levelSlice[0]); err != nil {
-			return nil, errors.Wrapf(err, "failed to parse low level %q", levelSlice[0])
+			return nil, fmt.Errorf("failed to parse low level %q: %w", levelSlice[0], err)
 		}
 	}
 
@@ -533,37 +548,30 @@ func rangeStrToMLSRange(rangeStr string) (*mlsRange, error) {
 
 // bitsetToStr takes a category bitset and returns it in the
 // canonical selinux syntax
-func bitsetToStr(c *bitset.BitSet) string {
+func bitsetToStr(c *big.Int) string {
 	var str string
-	i, e := c.NextSet(0)
-	len := 0
-	for e {
-		if len == 0 {
+
+	length := 0
+	for i := int(c.TrailingZeroBits()); i < c.BitLen(); i++ {
+		if c.Bit(i) == 0 {
+			continue
+		}
+		if length == 0 {
 			if str != "" {
 				str += ","
 			}
-			str += "c" + strconv.Itoa(int(i))
+			str += "c" + strconv.Itoa(i)
 		}
-
-		next, e := c.NextSet(i + 1)
-		if e {
-			// consecutive cats
-			if next == i+1 {
-				len++
-				i = next
-				continue
-			}
-		}
-		if len == 1 {
-			str += ",c" + strconv.Itoa(int(i))
-		} else if len > 1 {
-			str += ".c" + strconv.Itoa(int(i))
+		if c.Bit(i+1) == 1 {
+			length++
+			continue
 		}
-		if !e {
-			break
+		if length == 1 {
+			str += ",c" + strconv.Itoa(i)
+		} else if length > 1 {
+			str += ".c" + strconv.Itoa(i)
 		}
-		len = 0
-		i = next
+		length = 0
 	}
 
 	return str
@@ -576,13 +584,16 @@ func (l1 *level) equal(l2 *level) bool {
 	if l1.sens != l2.sens {
 		return false
 	}
-	return l1.cats.Equal(l2.cats)
+	if l2.cats == nil || l1.cats == nil {
+		return l2.cats == l1.cats
+	}
+	return l1.cats.Cmp(l2.cats) == 0
 }
 
 // String returns an mlsRange as a string.
 func (m mlsRange) String() string {
 	low := "s" + strconv.Itoa(int(m.low.sens))
-	if m.low.cats != nil && m.low.cats.Count() > 0 {
+	if m.low.cats != nil && m.low.cats.BitLen() > 0 {
 		low += ":" + bitsetToStr(m.low.cats)
 	}
 
@@ -591,7 +602,7 @@ func (m mlsRange) String() string {
 	}
 
 	high := "s" + strconv.Itoa(int(m.high.sens))
-	if m.high.cats != nil && m.high.cats.Count() > 0 {
+	if m.high.cats != nil && m.high.cats.BitLen() > 0 {
 		high += ":" + bitsetToStr(m.high.cats)
 	}
 
@@ -641,10 +652,12 @@ func calculateGlbLub(sourceRange, targetRange string) (string, error) {
 
 	/* find the intersecting categories */
 	if s.low.cats != nil && t.low.cats != nil {
-		outrange.low.cats = s.low.cats.Intersection(t.low.cats)
+		outrange.low.cats = new(big.Int)
+		outrange.low.cats.And(s.low.cats, t.low.cats)
 	}
 	if s.high.cats != nil && t.high.cats != nil {
-		outrange.high.cats = s.high.cats.Intersection(t.high.cats)
+		outrange.high.cats = new(big.Int)
+		outrange.high.cats.And(s.high.cats, t.high.cats)
 	}
 
 	return outrange.String(), nil
@@ -665,11 +678,7 @@ func readWriteCon(fpath string, val string) (string, error) {
 		return "", err
 	}
 
-	var retval string
-	if _, err := fmt.Fscanf(f, "%s", &retval); err != nil {
-		return "", err
-	}
-	return strings.Trim(retval, "\x00"), nil
+	return readConFd(f)
 }
 
 // setExecLabel sets the SELinux label that the kernel will use for any programs
@@ -697,17 +706,21 @@ func socketLabel() (string, error) {
 
 // peerLabel retrieves the label of the client on the other side of a socket
 func peerLabel(fd uintptr) (string, error) {
-	return unix.GetsockoptString(int(fd), unix.SOL_SOCKET, unix.SO_PEERSEC)
+	label, err := unix.GetsockoptString(int(fd), unix.SOL_SOCKET, unix.SO_PEERSEC)
+	if err != nil {
+		return "", &os.PathError{Op: "getsockopt", Path: "fd " + strconv.Itoa(int(fd)), Err: err}
+	}
+	return label, nil
 }
 
 // setKeyLabel takes a process label and tells the kernel to assign the
 // label to the next kernel keyring that gets created
 func setKeyLabel(label string) error {
 	err := writeCon("/proc/self/attr/keycreate", label)
-	if os.IsNotExist(errors.Cause(err)) {
+	if errors.Is(err, os.ErrNotExist) {
 		return nil
 	}
-	if label == "" && os.IsPermission(errors.Cause(err)) {
+	if label == "" && errors.Is(err, os.ErrPermission) {
 		return nil
 	}
 	return err
@@ -720,10 +733,10 @@ func keyLabel() (string, error) {
 
 // get returns the Context as a string
 func (c Context) get() string {
-	if c["level"] != "" {
-		return fmt.Sprintf("%s:%s:%s:%s", c["user"], c["role"], c["type"], c["level"])
+	if level := c["level"]; level != "" {
+		return c["user"] + ":" + c["role"] + ":" + c["type"] + ":" + level
 	}
-	return fmt.Sprintf("%s:%s:%s", c["user"], c["role"], c["type"])
+	return c["user"] + ":" + c["role"] + ":" + c["type"]
 }
 
 // newContext creates a new Context struct from the specified label
@@ -784,7 +797,7 @@ func enforceMode() int {
 // setEnforceMode sets the current SELinux mode Enforcing, Permissive.
 // Disabled is not valid, since this needs to be set at boot time.
 func setEnforceMode(mode int) error {
-	return ioutil.WriteFile(selinuxEnforcePath(), []byte(strconv.Itoa(mode)), 0644)
+	return ioutil.WriteFile(selinuxEnforcePath(), []byte(strconv.Itoa(mode)), 0o644)
 }
 
 // defaultEnforceMode returns the systems default SELinux mode Enforcing,
@@ -888,24 +901,21 @@ func openContextFile() (*os.File, error) {
 	if f, err := os.Open(contextFile); err == nil {
 		return f, nil
 	}
-	lxcPath := filepath.Join(policyRoot, "/contexts/lxc_contexts")
-	return os.Open(lxcPath)
+	return os.Open(filepath.Join(policyRoot(), "/contexts/lxc_contexts"))
 }
 
-var labels, privContainerMountLabel = loadLabels()
-
-func loadLabels() (map[string]string, string) {
-	labels := make(map[string]string)
+func loadLabels() {
+	labels = make(map[string]string)
 	in, err := openContextFile()
 	if err != nil {
-		return labels, ""
+		return
 	}
 	defer in.Close()
 
 	scanner := bufio.NewScanner(in)
 
 	for scanner.Scan() {
-		line := strings.TrimSpace(scanner.Text())
+		line := bytes.TrimSpace(scanner.Bytes())
 		if len(line) == 0 {
 			// Skip blank lines
 			continue
@@ -914,38 +924,47 @@ func loadLabels() (map[string]string, string) {
 			// Skip comments
 			continue
 		}
-		if groups := assignRegex.FindStringSubmatch(line); groups != nil {
-			key, val := strings.TrimSpace(groups[1]), strings.TrimSpace(groups[2])
-			labels[key] = strings.Trim(val, "\"")
+		fields := bytes.SplitN(line, []byte{'='}, 2)
+		if len(fields) != 2 {
+			continue
 		}
+		key, val := bytes.TrimSpace(fields[0]), bytes.TrimSpace(fields[1])
+		labels[string(key)] = string(bytes.Trim(val, `"`))
 	}
 
 	con, _ := NewContext(labels["file"])
 	con["level"] = fmt.Sprintf("s0:c%d,c%d", maxCategory-2, maxCategory-1)
-	reserveLabel(con.get())
-	return labels, con.get()
+	privContainerMountLabel = con.get()
+	reserveLabel(privContainerMountLabel)
+}
+
+func label(key string) string {
+	loadLabelsOnce.Do(func() {
+		loadLabels()
+	})
+	return labels[key]
 }
 
 // kvmContainerLabels returns the default processLabel and mountLabel to be used
 // for kvm containers by the calling process.
 func kvmContainerLabels() (string, string) {
-	processLabel := labels["kvm_process"]
+	processLabel := label("kvm_process")
 	if processLabel == "" {
-		processLabel = labels["process"]
+		processLabel = label("process")
 	}
 
-	return addMcs(processLabel, labels["file"])
+	return addMcs(processLabel, label("file"))
 }
 
 // initContainerLabels returns the default processLabel and file labels to be
 // used for containers running an init system like systemd by the calling process.
 func initContainerLabels() (string, string) {
-	processLabel := labels["init_process"]
+	processLabel := label("init_process")
 	if processLabel == "" {
-		processLabel = labels["process"]
+		processLabel = label("process")
 	}
 
-	return addMcs(processLabel, labels["file"])
+	return addMcs(processLabel, label("file"))
 }
 
 // containerLabels returns an allocated processLabel and fileLabel to be used for
@@ -955,9 +974,9 @@ func containerLabels() (processLabel string, fileLabel string) {
 		return "", ""
 	}
 
-	processLabel = labels["process"]
-	fileLabel = labels["file"]
-	readOnlyFileLabel = labels["ro_file"]
+	processLabel = label("process")
+	fileLabel = label("file")
+	readOnlyFileLabel = label("ro_file")
 
 	if processLabel == "" || fileLabel == "" {
 		return "", fileLabel
@@ -985,7 +1004,7 @@ func addMcs(processLabel, fileLabel string) (string, string) {
 
 // securityCheckContext validates that the SELinux label is understood by the kernel
 func securityCheckContext(val string) error {
-	return ioutil.WriteFile(path.Join(getSelinuxMountPoint(), "context"), []byte(val), 0644)
+	return ioutil.WriteFile(path.Join(getSelinuxMountPoint(), "context"), []byte(val), 0o644)
 }
 
 // copyLevel returns a label with the MLS/MCS level from src label replaced on
@@ -1023,7 +1042,7 @@ func badPrefix(fpath string) error {
 	badPrefixes := []string{"/usr"}
 	for _, prefix := range badPrefixes {
 		if strings.HasPrefix(fpath, prefix) {
-			return errors.Errorf("relabeling content in %s is not allowed", prefix)
+			return fmt.Errorf("relabeling content in %s is not allowed", prefix)
 		}
 	}
 	return nil
@@ -1044,17 +1063,10 @@ func chcon(fpath string, label string, recurse bool) error {
 	}
 
 	if !recurse {
-		return SetFileLabel(fpath, label)
+		return setFileLabel(fpath, label)
 	}
 
-	return pwalk.Walk(fpath, func(p string, info os.FileInfo, err error) error {
-		e := SetFileLabel(p, label)
-		// Walk a file tree can race with removal, so ignore ENOENT
-		if os.IsNotExist(errors.Cause(e)) {
-			return nil
-		}
-		return e
-	})
+	return rchcon(fpath, label)
 }
 
 // dupSecOpt takes an SELinux process label and returns security options that
@@ -1072,7 +1084,8 @@ func dupSecOpt(src string) ([]string, error) {
 		con["type"] == "" {
 		return nil, nil
 	}
-	dup := []string{"user:" + con["user"],
+	dup := []string{
+		"user:" + con["user"],
 		"role:" + con["role"],
 		"type:" + con["type"],
 	}
@@ -1140,9 +1153,8 @@ func findUserInContext(context Context, r io.Reader, verifier func(string) error
 			return outConn, nil
 		}
 	}
-
 	if err := scanner.Err(); err != nil {
-		return "", errors.Wrap(err, "failed to scan for context")
+		return "", fmt.Errorf("failed to scan for context: %w", err)
 	}
 
 	return "", nil
@@ -1155,7 +1167,7 @@ func getDefaultContextFromReaders(c *defaultSECtx) (string, error) {
 
 	context, err := newContext(c.scon)
 	if err != nil {
-		return "", errors.Wrapf(err, "failed to create label for %s", c.scon)
+		return "", fmt.Errorf("failed to create label for %s: %w", c.scon, err)
 	}
 
 	// set so the verifier validates the matched context with the provided user and level.
@@ -1180,19 +1192,18 @@ func getDefaultContextFromReaders(c *defaultSECtx) (string, error) {
 		return conn, nil
 	}
 
-	return "", errors.Wrapf(ErrContextMissing, "context not found: %q", c.scon)
+	return "", fmt.Errorf("context %q not found: %w", c.scon, ErrContextMissing)
 }
 
 func getDefaultContextWithLevel(user, level, scon string) (string, error) {
-	userPath := filepath.Join(policyRoot, selinuxUsersDir, user)
-	defaultPath := filepath.Join(policyRoot, defaultContexts)
-
+	userPath := filepath.Join(policyRoot(), selinuxUsersDir, user)
 	fu, err := os.Open(userPath)
 	if err != nil {
 		return "", err
 	}
 	defer fu.Close()
 
+	defaultPath := filepath.Join(policyRoot(), defaultContexts)
 	fd, err := os.Open(defaultPath)
 	if err != nil {
 		return "", err

+ 4 - 2
vendor/github.com/opencontainers/selinux/go-selinux/selinux_stub.go

@@ -2,8 +2,6 @@
 
 package selinux
 
-const privContainerMountLabel = ""
-
 func setDisabled() {
 }
 
@@ -152,3 +150,7 @@ func disableSecOpt() []string {
 func getDefaultContextWithLevel(user, level, scon string) (string, error) {
 	return "", nil
 }
+
+func label(_ string) string {
+	return ""
+}

+ 2 - 2
vendor/github.com/opencontainers/selinux/go-selinux/xattrs_linux.go

@@ -10,7 +10,7 @@ func lgetxattr(path, attr string) ([]byte, error) {
 	// Start with a 128 length byte array
 	dest := make([]byte, 128)
 	sz, errno := doLgetxattr(path, attr, dest)
-	for errno == unix.ERANGE {
+	for errno == unix.ERANGE { //nolint:errorlint // unix errors are bare
 		// Buffer too small, use zero-sized buffer to get the actual size
 		sz, errno = doLgetxattr(path, attr, []byte{})
 		if errno != nil {
@@ -31,7 +31,7 @@ func lgetxattr(path, attr string) ([]byte, error) {
 func doLgetxattr(path, attr string, dest []byte) (int, error) {
 	for {
 		sz, err := unix.Lgetxattr(path, attr, dest)
-		if err != unix.EINTR {
+		if err != unix.EINTR { //nolint:errorlint // unix errors are bare
 			return sz, err
 		}
 	}

+ 1 - 5
vendor/github.com/opencontainers/selinux/go.mod

@@ -2,8 +2,4 @@ module github.com/opencontainers/selinux
 
 go 1.13
 
-require (
-	github.com/bits-and-blooms/bitset v1.2.0
-	github.com/pkg/errors v0.9.1
-	golang.org/x/sys v0.0.0-20191115151921-52ab43148777
-)
+require golang.org/x/sys v0.0.0-20191115151921-52ab43148777

+ 6 - 0
vendor/github.com/opencontainers/selinux/pkg/pwalk/README.md

@@ -8,6 +8,12 @@ By default, it utilizes 2\*runtime.NumCPU() goroutines for callbacks.
 This can be changed by using WalkN function which has the additional
 parameter, specifying the number of goroutines (concurrency).
 
+### pwalk vs pwalkdir
+
+This package is deprecated in favor of
+[pwalkdir](https://pkg.go.dev/github.com/opencontainers/selinux/pkg/pwalkdir),
+which is faster, but requires at least Go 1.16.
+
 ### Caveats
 
 Please note the following limitations of this code:

+ 16 - 5
vendor/github.com/opencontainers/selinux/pkg/pwalk/pwalk.go

@@ -1,12 +1,11 @@
 package pwalk
 
 import (
+	"fmt"
 	"os"
 	"path/filepath"
 	"runtime"
 	"sync"
-
-	"github.com/pkg/errors"
 )
 
 type WalkFunc = filepath.WalkFunc
@@ -20,7 +19,7 @@ type WalkFunc = filepath.WalkFunc
 //
 // Note that this implementation only supports primitive error handling:
 //
-// - no errors are ever passed to WalkFn;
+// - no errors are ever passed to walkFn;
 //
 // - once a walkFn returns any error, all further processing stops
 // and the error is returned to the caller of Walk;
@@ -42,7 +41,7 @@ func Walk(root string, walkFn WalkFunc) error {
 func WalkN(root string, walkFn WalkFunc, num int) error {
 	// make sure limit is sensible
 	if num < 1 {
-		return errors.Errorf("walk(%q): num must be > 0", root)
+		return fmt.Errorf("walk(%q): num must be > 0", root)
 	}
 
 	files := make(chan *walkArgs, 2*num)
@@ -52,6 +51,9 @@ func WalkN(root string, walkFn WalkFunc, num int) error {
 	var (
 		err error
 		wg  sync.WaitGroup
+
+		rootLen   = len(root)
+		rootEntry *walkArgs
 	)
 	wg.Add(1)
 	go func() {
@@ -60,6 +62,11 @@ func WalkN(root string, walkFn WalkFunc, num int) error {
 				close(files)
 				return err
 			}
+			if len(p) == rootLen {
+				// Root entry is processed separately below.
+				rootEntry = &walkArgs{path: p, info: &info}
+				return nil
+			}
 			// add a file to the queue unless a callback sent an error
 			select {
 			case e := <-errCh:
@@ -93,10 +100,14 @@ func WalkN(root string, walkFn WalkFunc, num int) error {
 
 	wg.Wait()
 
+	if err == nil {
+		err = walkFn(rootEntry.path, *rootEntry.info, nil)
+	}
+
 	return err
 }
 
-// walkArgs holds the arguments that were passed to the Walk or WalkLimit
+// walkArgs holds the arguments that were passed to the Walk or WalkN
 // functions.
 type walkArgs struct {
 	path string

+ 54 - 0
vendor/github.com/opencontainers/selinux/pkg/pwalkdir/README.md

@@ -0,0 +1,54 @@
+## pwalkdir: parallel implementation of filepath.WalkDir
+
+This is a wrapper for [filepath.WalkDir](https://pkg.go.dev/path/filepath#WalkDir)
+which may speed it up by calling multiple callback functions (WalkDirFunc)
+in parallel, utilizing goroutines.
+
+By default, it utilizes 2\*runtime.NumCPU() goroutines for callbacks.
+This can be changed by using WalkN function which has the additional
+parameter, specifying the number of goroutines (concurrency).
+
+### pwalk vs pwalkdir
+
+This package is very similar to
+[pwalk](https://pkg.go.dev/github.com/opencontainers/selinux/pkg/pwalkdir),
+but utilizes `filepath.WalkDir` (added to Go 1.16), which does not call stat(2)
+on every entry and is therefore faster (up to 3x, depending on usage scenario).
+
+Users who are OK with requiring Go 1.16+ should switch to this
+implementation.
+
+### Caveats
+
+Please note the following limitations of this code:
+
+* Unlike filepath.WalkDir, the order of calls is non-deterministic;
+
+* Only primitive error handling is supported:
+
+  * fs.SkipDir is not supported;
+
+  * no errors are ever passed to WalkDirFunc;
+
+  * once any error is returned from any walkDirFunc instance, no more calls
+    to WalkDirFunc are made, and the error is returned to the caller of WalkDir;
+
+  * if more than one WalkDirFunc instance will return an error, only one
+    of such errors will be propagated to and returned by WalkDir, others
+    will be silently discarded.
+
+### Documentation
+
+For the official documentation, see
+https://pkg.go.dev/github.com/opencontainers/selinux/pkg/pwalkdir
+
+### Benchmarks
+
+For a WalkDirFunc that consists solely of the return statement, this
+implementation is about 15% slower than the standard library's
+filepath.WalkDir.
+
+Otherwise (if a WalkDirFunc is actually doing something) this is usually
+faster, except when the WalkDirN(..., 1) is used. Run `go test -bench .`
+to see how different operations can benefit from it, as well as how the
+level of paralellism affects the speed.

+ 116 - 0
vendor/github.com/opencontainers/selinux/pkg/pwalkdir/pwalkdir.go

@@ -0,0 +1,116 @@
+//go:build go1.16
+// +build go1.16
+
+package pwalkdir
+
+import (
+	"fmt"
+	"io/fs"
+	"path/filepath"
+	"runtime"
+	"sync"
+)
+
+// Walk is a wrapper for filepath.WalkDir which can call multiple walkFn
+// in parallel, allowing to handle each item concurrently. A maximum of
+// twice the runtime.NumCPU() walkFn will be called at any one time.
+// If you want to change the maximum, use WalkN instead.
+//
+// The order of calls is non-deterministic.
+//
+// Note that this implementation only supports primitive error handling:
+//
+// - no errors are ever passed to walkFn;
+//
+// - once a walkFn returns any error, all further processing stops
+// and the error is returned to the caller of Walk;
+//
+// - filepath.SkipDir is not supported;
+//
+// - if more than one walkFn instance will return an error, only one
+// of such errors will be propagated and returned by Walk, others
+// will be silently discarded.
+func Walk(root string, walkFn fs.WalkDirFunc) error {
+	return WalkN(root, walkFn, runtime.NumCPU()*2)
+}
+
+// WalkN is a wrapper for filepath.WalkDir which can call multiple walkFn
+// in parallel, allowing to handle each item concurrently. A maximum of
+// num walkFn will be called at any one time.
+//
+// Please see Walk documentation for caveats of using this function.
+func WalkN(root string, walkFn fs.WalkDirFunc, num int) error {
+	// make sure limit is sensible
+	if num < 1 {
+		return fmt.Errorf("walk(%q): num must be > 0", root)
+	}
+
+	files := make(chan *walkArgs, 2*num)
+	errCh := make(chan error, 1) // Get the first error, ignore others.
+
+	// Start walking a tree asap.
+	var (
+		err error
+		wg  sync.WaitGroup
+
+		rootLen   = len(root)
+		rootEntry *walkArgs
+	)
+	wg.Add(1)
+	go func() {
+		err = filepath.WalkDir(root, func(p string, entry fs.DirEntry, err error) error {
+			if err != nil {
+				close(files)
+				return err
+			}
+			if len(p) == rootLen {
+				// Root entry is processed separately below.
+				rootEntry = &walkArgs{path: p, entry: entry}
+				return nil
+			}
+			// Add a file to the queue unless a callback sent an error.
+			select {
+			case e := <-errCh:
+				close(files)
+				return e
+			default:
+				files <- &walkArgs{path: p, entry: entry}
+				return nil
+			}
+		})
+		if err == nil {
+			close(files)
+		}
+		wg.Done()
+	}()
+
+	wg.Add(num)
+	for i := 0; i < num; i++ {
+		go func() {
+			for file := range files {
+				if e := walkFn(file.path, file.entry, nil); e != nil {
+					select {
+					case errCh <- e: // sent ok
+					default: // buffer full
+					}
+				}
+			}
+			wg.Done()
+		}()
+	}
+
+	wg.Wait()
+
+	if err == nil {
+		err = walkFn(rootEntry.path, rootEntry.entry, nil)
+	}
+
+	return err
+}
+
+// walkArgs holds the arguments that were passed to the Walk or WalkN
+// functions.
+type walkArgs struct {
+	path  string
+	entry fs.DirEntry
+}