github.com/SagerNet/gvisor@v0.0.0-20210707092255-7731c139d75c/pkg/sentry/kernel/semaphore/semaphore.go (about)

     1  // Copyright 2018 The gVisor Authors.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  // Package semaphore implements System V semaphores.
    16  package semaphore
    17  
    18  import (
    19  	"fmt"
    20  
    21  	"github.com/SagerNet/gvisor/pkg/abi/linux"
    22  	"github.com/SagerNet/gvisor/pkg/context"
    23  	"github.com/SagerNet/gvisor/pkg/errors/linuxerr"
    24  	"github.com/SagerNet/gvisor/pkg/log"
    25  	"github.com/SagerNet/gvisor/pkg/sentry/fs"
    26  	"github.com/SagerNet/gvisor/pkg/sentry/kernel/auth"
    27  	ktime "github.com/SagerNet/gvisor/pkg/sentry/kernel/time"
    28  	"github.com/SagerNet/gvisor/pkg/sync"
    29  	"github.com/SagerNet/gvisor/pkg/syserror"
    30  )
    31  
    32  const (
    33  	// Maximum semaphore value.
    34  	valueMax = linux.SEMVMX
    35  
    36  	// Maximum number of semaphore sets.
    37  	setsMax = linux.SEMMNI
    38  
    39  	// Maximum number of semaphores in a semaphore set.
    40  	semsMax = linux.SEMMSL
    41  
    42  	// Maximum number of semaphores in all semaphore sets.
    43  	semsTotalMax = linux.SEMMNS
    44  )
    45  
    46  // Registry maintains a set of semaphores that can be found by key or ID.
    47  //
    48  // +stateify savable
    49  type Registry struct {
    50  	// userNS owning the ipc name this registry belongs to. Immutable.
    51  	userNS *auth.UserNamespace
    52  	// mu protects all fields below.
    53  	mu         sync.Mutex `state:"nosave"`
    54  	semaphores map[int32]*Set
    55  	lastIDUsed int32
    56  	// indexes maintains a mapping between a set's index in virtual array and
    57  	// its identifier.
    58  	indexes map[int32]int32
    59  }
    60  
    61  // Set represents a set of semaphores that can be operated atomically.
    62  //
    63  // +stateify savable
    64  type Set struct {
    65  	// registry owning this sem set. Immutable.
    66  	registry *Registry
    67  
    68  	// Id is a handle that identifies the set.
    69  	ID int32
    70  
    71  	// key is an user provided key that can be shared between processes.
    72  	key int32
    73  
    74  	// creator is the user that created the set. Immutable.
    75  	creator fs.FileOwner
    76  
    77  	// mu protects all fields below.
    78  	mu         sync.Mutex `state:"nosave"`
    79  	owner      fs.FileOwner
    80  	perms      fs.FilePermissions
    81  	opTime     ktime.Time
    82  	changeTime ktime.Time
    83  
    84  	// sems holds all semaphores in the set. The slice itself is immutable after
    85  	// it's been set, however each 'sem' object in the slice requires 'mu' lock.
    86  	sems []sem
    87  
    88  	// dead is set to true when the set is removed and can't be reached anymore.
    89  	// All waiters must wake up and fail when set is dead.
    90  	dead bool
    91  }
    92  
    93  // sem represents a single semaphore from a set.
    94  //
    95  // +stateify savable
    96  type sem struct {
    97  	value   int16
    98  	waiters waiterList `state:"zerovalue"`
    99  	pid     int32
   100  }
   101  
   102  // waiter represents a caller that is waiting for the semaphore value to
   103  // become positive or zero.
   104  //
   105  // +stateify savable
   106  type waiter struct {
   107  	waiterEntry
   108  
   109  	// value represents how much resource the waiter needs to wake up.
   110  	// The value is either 0 or negative.
   111  	value int16
   112  	ch    chan struct{}
   113  }
   114  
   115  // NewRegistry creates a new semaphore set registry.
   116  func NewRegistry(userNS *auth.UserNamespace) *Registry {
   117  	return &Registry{
   118  		userNS:     userNS,
   119  		semaphores: make(map[int32]*Set),
   120  		indexes:    make(map[int32]int32),
   121  	}
   122  }
   123  
   124  // FindOrCreate searches for a semaphore set that matches 'key'. If not found,
   125  // it may create a new one if requested. If private is true, key is ignored and
   126  // a new set is always created. If create is false, it fails if a set cannot
   127  // be found. If exclusive is true, it fails if a set with the same key already
   128  // exists.
   129  func (r *Registry) FindOrCreate(ctx context.Context, key, nsems int32, mode linux.FileMode, private, create, exclusive bool) (*Set, error) {
   130  	if nsems < 0 || nsems > semsMax {
   131  		return nil, linuxerr.EINVAL
   132  	}
   133  
   134  	r.mu.Lock()
   135  	defer r.mu.Unlock()
   136  
   137  	if !private {
   138  		// Look up an existing semaphore.
   139  		if set := r.findByKey(key); set != nil {
   140  			set.mu.Lock()
   141  			defer set.mu.Unlock()
   142  
   143  			// Check that caller can access semaphore set.
   144  			creds := auth.CredentialsFromContext(ctx)
   145  			if !set.checkPerms(creds, fs.PermsFromMode(mode)) {
   146  				return nil, linuxerr.EACCES
   147  			}
   148  
   149  			// Validate parameters.
   150  			if nsems > int32(set.Size()) {
   151  				return nil, linuxerr.EINVAL
   152  			}
   153  			if create && exclusive {
   154  				return nil, syserror.EEXIST
   155  			}
   156  			return set, nil
   157  		}
   158  
   159  		if !create {
   160  			// Semaphore not found and should not be created.
   161  			return nil, syserror.ENOENT
   162  		}
   163  	}
   164  
   165  	// Zero is only valid if an existing set is found.
   166  	if nsems == 0 {
   167  		return nil, linuxerr.EINVAL
   168  	}
   169  
   170  	// Apply system limits.
   171  	//
   172  	// Map semaphores and map indexes in a registry are of the same size,
   173  	// check map semaphores only here for the system limit.
   174  	if len(r.semaphores) >= setsMax {
   175  		return nil, syserror.ENOSPC
   176  	}
   177  	if r.totalSems() > int(semsTotalMax-nsems) {
   178  		return nil, syserror.ENOSPC
   179  	}
   180  
   181  	// Finally create a new set.
   182  	owner := fs.FileOwnerFromContext(ctx)
   183  	perms := fs.FilePermsFromMode(mode)
   184  	return r.newSet(ctx, key, owner, owner, perms, nsems)
   185  }
   186  
   187  // IPCInfo returns information about system-wide semaphore limits and parameters.
   188  func (r *Registry) IPCInfo() *linux.SemInfo {
   189  	return &linux.SemInfo{
   190  		SemMap: linux.SEMMAP,
   191  		SemMni: linux.SEMMNI,
   192  		SemMns: linux.SEMMNS,
   193  		SemMnu: linux.SEMMNU,
   194  		SemMsl: linux.SEMMSL,
   195  		SemOpm: linux.SEMOPM,
   196  		SemUme: linux.SEMUME,
   197  		SemUsz: linux.SEMUSZ,
   198  		SemVmx: linux.SEMVMX,
   199  		SemAem: linux.SEMAEM,
   200  	}
   201  }
   202  
   203  // SemInfo returns a seminfo structure containing the same information as
   204  // for IPC_INFO, except that SemUsz field returns the number of existing
   205  // semaphore sets, and SemAem field returns the number of existing semaphores.
   206  func (r *Registry) SemInfo() *linux.SemInfo {
   207  	r.mu.Lock()
   208  	defer r.mu.Unlock()
   209  
   210  	info := r.IPCInfo()
   211  	info.SemUsz = uint32(len(r.semaphores))
   212  	info.SemAem = uint32(r.totalSems())
   213  
   214  	return info
   215  }
   216  
   217  // HighestIndex returns the index of the highest used entry in
   218  // the kernel's array.
   219  func (r *Registry) HighestIndex() int32 {
   220  	r.mu.Lock()
   221  	defer r.mu.Unlock()
   222  
   223  	// By default, highest used index is 0 even though
   224  	// there is no semaphore set.
   225  	var highestIndex int32
   226  	for index := range r.indexes {
   227  		if index > highestIndex {
   228  			highestIndex = index
   229  		}
   230  	}
   231  	return highestIndex
   232  }
   233  
   234  // RemoveID removes set with give 'id' from the registry and marks the set as
   235  // dead. All waiters will be awakened and fail.
   236  func (r *Registry) RemoveID(id int32, creds *auth.Credentials) error {
   237  	r.mu.Lock()
   238  	defer r.mu.Unlock()
   239  
   240  	set := r.semaphores[id]
   241  	if set == nil {
   242  		return linuxerr.EINVAL
   243  	}
   244  	index, found := r.findIndexByID(id)
   245  	if !found {
   246  		// Inconsistent state.
   247  		panic(fmt.Sprintf("unable to find an index for ID: %d", id))
   248  	}
   249  
   250  	set.mu.Lock()
   251  	defer set.mu.Unlock()
   252  
   253  	// "The effective user ID of the calling process must match the creator or
   254  	// owner of the semaphore set, or the caller must be privileged."
   255  	if !set.checkCredentials(creds) && !set.checkCapability(creds) {
   256  		return linuxerr.EACCES
   257  	}
   258  
   259  	delete(r.semaphores, set.ID)
   260  	delete(r.indexes, index)
   261  	set.destroy()
   262  	return nil
   263  }
   264  
   265  func (r *Registry) newSet(ctx context.Context, key int32, owner, creator fs.FileOwner, perms fs.FilePermissions, nsems int32) (*Set, error) {
   266  	set := &Set{
   267  		registry:   r,
   268  		key:        key,
   269  		owner:      owner,
   270  		creator:    owner,
   271  		perms:      perms,
   272  		changeTime: ktime.NowFromContext(ctx),
   273  		sems:       make([]sem, nsems),
   274  	}
   275  
   276  	// Find the next available ID.
   277  	for id := r.lastIDUsed + 1; id != r.lastIDUsed; id++ {
   278  		// Handle wrap around.
   279  		if id < 0 {
   280  			id = 0
   281  			continue
   282  		}
   283  		if r.semaphores[id] == nil {
   284  			index, found := r.findFirstAvailableIndex()
   285  			if !found {
   286  				panic("unable to find an available index")
   287  			}
   288  			r.indexes[index] = id
   289  			r.lastIDUsed = id
   290  			r.semaphores[id] = set
   291  			set.ID = id
   292  			return set, nil
   293  		}
   294  	}
   295  
   296  	log.Warningf("Semaphore map is full, they must be leaking")
   297  	return nil, syserror.ENOMEM
   298  }
   299  
   300  // FindByID looks up a set given an ID.
   301  func (r *Registry) FindByID(id int32) *Set {
   302  	r.mu.Lock()
   303  	defer r.mu.Unlock()
   304  	return r.semaphores[id]
   305  }
   306  
   307  // FindByIndex looks up a set given an index.
   308  func (r *Registry) FindByIndex(index int32) *Set {
   309  	r.mu.Lock()
   310  	defer r.mu.Unlock()
   311  
   312  	id, present := r.indexes[index]
   313  	if !present {
   314  		return nil
   315  	}
   316  	return r.semaphores[id]
   317  }
   318  
   319  func (r *Registry) findByKey(key int32) *Set {
   320  	for _, v := range r.semaphores {
   321  		if v.key == key {
   322  			return v
   323  		}
   324  	}
   325  	return nil
   326  }
   327  
   328  func (r *Registry) findIndexByID(id int32) (int32, bool) {
   329  	for k, v := range r.indexes {
   330  		if v == id {
   331  			return k, true
   332  		}
   333  	}
   334  	return 0, false
   335  }
   336  
   337  func (r *Registry) findFirstAvailableIndex() (int32, bool) {
   338  	for index := int32(0); index < setsMax; index++ {
   339  		if _, present := r.indexes[index]; !present {
   340  			return index, true
   341  		}
   342  	}
   343  	return 0, false
   344  }
   345  
   346  func (r *Registry) totalSems() int {
   347  	totalSems := 0
   348  	for _, v := range r.semaphores {
   349  		totalSems += v.Size()
   350  	}
   351  	return totalSems
   352  }
   353  
   354  func (s *Set) findSem(num int32) *sem {
   355  	if num < 0 || int(num) >= s.Size() {
   356  		return nil
   357  	}
   358  	return &s.sems[num]
   359  }
   360  
   361  // Size returns the number of semaphores in the set. Size is immutable.
   362  func (s *Set) Size() int {
   363  	return len(s.sems)
   364  }
   365  
   366  // Change changes some fields from the set atomically.
   367  func (s *Set) Change(ctx context.Context, creds *auth.Credentials, owner fs.FileOwner, perms fs.FilePermissions) error {
   368  	s.mu.Lock()
   369  	defer s.mu.Unlock()
   370  
   371  	// "The effective UID of the calling process must match the owner or creator
   372  	// of the semaphore set, or the caller must be privileged."
   373  	if !s.checkCredentials(creds) && !s.checkCapability(creds) {
   374  		return linuxerr.EACCES
   375  	}
   376  
   377  	s.owner = owner
   378  	s.perms = perms
   379  	s.changeTime = ktime.NowFromContext(ctx)
   380  	return nil
   381  }
   382  
   383  // GetStat extracts semid_ds information from the set.
   384  func (s *Set) GetStat(creds *auth.Credentials) (*linux.SemidDS, error) {
   385  	// "The calling process must have read permission on the semaphore set."
   386  	return s.semStat(creds, fs.PermMask{Read: true})
   387  }
   388  
   389  // GetStatAny extracts semid_ds information from the set without requiring read access.
   390  func (s *Set) GetStatAny(creds *auth.Credentials) (*linux.SemidDS, error) {
   391  	return s.semStat(creds, fs.PermMask{})
   392  }
   393  
   394  func (s *Set) semStat(creds *auth.Credentials, permMask fs.PermMask) (*linux.SemidDS, error) {
   395  	s.mu.Lock()
   396  	defer s.mu.Unlock()
   397  
   398  	if !s.checkPerms(creds, permMask) {
   399  		return nil, linuxerr.EACCES
   400  	}
   401  
   402  	return &linux.SemidDS{
   403  		SemPerm: linux.IPCPerm{
   404  			Key:  uint32(s.key),
   405  			UID:  uint32(creds.UserNamespace.MapFromKUID(s.owner.UID)),
   406  			GID:  uint32(creds.UserNamespace.MapFromKGID(s.owner.GID)),
   407  			CUID: uint32(creds.UserNamespace.MapFromKUID(s.creator.UID)),
   408  			CGID: uint32(creds.UserNamespace.MapFromKGID(s.creator.GID)),
   409  			Mode: uint16(s.perms.LinuxMode()),
   410  			Seq:  0, // IPC sequence not supported.
   411  		},
   412  		SemOTime: s.opTime.TimeT(),
   413  		SemCTime: s.changeTime.TimeT(),
   414  		SemNSems: uint64(s.Size()),
   415  	}, nil
   416  }
   417  
   418  // SetVal overrides a semaphore value, waking up waiters as needed.
   419  func (s *Set) SetVal(ctx context.Context, num int32, val int16, creds *auth.Credentials, pid int32) error {
   420  	if val < 0 || val > valueMax {
   421  		return syserror.ERANGE
   422  	}
   423  
   424  	s.mu.Lock()
   425  	defer s.mu.Unlock()
   426  
   427  	// "The calling process must have alter permission on the semaphore set."
   428  	if !s.checkPerms(creds, fs.PermMask{Write: true}) {
   429  		return linuxerr.EACCES
   430  	}
   431  
   432  	sem := s.findSem(num)
   433  	if sem == nil {
   434  		return syserror.ERANGE
   435  	}
   436  
   437  	// TODO(github.com/SagerNet/issue/137): Clear undo entries in all processes.
   438  	sem.value = val
   439  	sem.pid = pid
   440  	s.changeTime = ktime.NowFromContext(ctx)
   441  	sem.wakeWaiters()
   442  	return nil
   443  }
   444  
   445  // SetValAll overrides all semaphores values, waking up waiters as needed. It also
   446  // sets semaphore's PID which was fixed in Linux 4.6.
   447  //
   448  // 'len(vals)' must be equal to 's.Size()'.
   449  func (s *Set) SetValAll(ctx context.Context, vals []uint16, creds *auth.Credentials, pid int32) error {
   450  	if len(vals) != s.Size() {
   451  		panic(fmt.Sprintf("vals length (%d) different that Set.Size() (%d)", len(vals), s.Size()))
   452  	}
   453  
   454  	for _, val := range vals {
   455  		if val > valueMax {
   456  			return syserror.ERANGE
   457  		}
   458  	}
   459  
   460  	s.mu.Lock()
   461  	defer s.mu.Unlock()
   462  
   463  	// "The calling process must have alter permission on the semaphore set."
   464  	if !s.checkPerms(creds, fs.PermMask{Write: true}) {
   465  		return linuxerr.EACCES
   466  	}
   467  
   468  	for i, val := range vals {
   469  		sem := &s.sems[i]
   470  
   471  		// TODO(github.com/SagerNet/issue/137): Clear undo entries in all processes.
   472  		sem.value = int16(val)
   473  		sem.pid = pid
   474  		sem.wakeWaiters()
   475  	}
   476  	s.changeTime = ktime.NowFromContext(ctx)
   477  	return nil
   478  }
   479  
   480  // GetVal returns a semaphore value.
   481  func (s *Set) GetVal(num int32, creds *auth.Credentials) (int16, error) {
   482  	s.mu.Lock()
   483  	defer s.mu.Unlock()
   484  
   485  	// "The calling process must have read permission on the semaphore set."
   486  	if !s.checkPerms(creds, fs.PermMask{Read: true}) {
   487  		return 0, linuxerr.EACCES
   488  	}
   489  
   490  	sem := s.findSem(num)
   491  	if sem == nil {
   492  		return 0, syserror.ERANGE
   493  	}
   494  	return sem.value, nil
   495  }
   496  
   497  // GetValAll returns value for all semaphores.
   498  func (s *Set) GetValAll(creds *auth.Credentials) ([]uint16, error) {
   499  	s.mu.Lock()
   500  	defer s.mu.Unlock()
   501  
   502  	// "The calling process must have read permission on the semaphore set."
   503  	if !s.checkPerms(creds, fs.PermMask{Read: true}) {
   504  		return nil, linuxerr.EACCES
   505  	}
   506  
   507  	vals := make([]uint16, s.Size())
   508  	for i, sem := range s.sems {
   509  		vals[i] = uint16(sem.value)
   510  	}
   511  	return vals, nil
   512  }
   513  
   514  // GetPID returns the PID set when performing operations in the semaphore.
   515  func (s *Set) GetPID(num int32, creds *auth.Credentials) (int32, error) {
   516  	s.mu.Lock()
   517  	defer s.mu.Unlock()
   518  
   519  	// "The calling process must have read permission on the semaphore set."
   520  	if !s.checkPerms(creds, fs.PermMask{Read: true}) {
   521  		return 0, linuxerr.EACCES
   522  	}
   523  
   524  	sem := s.findSem(num)
   525  	if sem == nil {
   526  		return 0, syserror.ERANGE
   527  	}
   528  	return sem.pid, nil
   529  }
   530  
   531  func (s *Set) countWaiters(num int32, creds *auth.Credentials, pred func(w *waiter) bool) (uint16, error) {
   532  	s.mu.Lock()
   533  	defer s.mu.Unlock()
   534  
   535  	// The calling process must have read permission on the semaphore set.
   536  	if !s.checkPerms(creds, fs.PermMask{Read: true}) {
   537  		return 0, linuxerr.EACCES
   538  	}
   539  
   540  	sem := s.findSem(num)
   541  	if sem == nil {
   542  		return 0, syserror.ERANGE
   543  	}
   544  	var cnt uint16
   545  	for w := sem.waiters.Front(); w != nil; w = w.Next() {
   546  		if pred(w) {
   547  			cnt++
   548  		}
   549  	}
   550  	return cnt, nil
   551  }
   552  
   553  // CountZeroWaiters returns number of waiters waiting for the sem's value to increase.
   554  func (s *Set) CountZeroWaiters(num int32, creds *auth.Credentials) (uint16, error) {
   555  	return s.countWaiters(num, creds, func(w *waiter) bool {
   556  		return w.value == 0
   557  	})
   558  }
   559  
   560  // CountNegativeWaiters returns number of waiters waiting for the sem to go to zero.
   561  func (s *Set) CountNegativeWaiters(num int32, creds *auth.Credentials) (uint16, error) {
   562  	return s.countWaiters(num, creds, func(w *waiter) bool {
   563  		return w.value < 0
   564  	})
   565  }
   566  
   567  // ExecuteOps attempts to execute a list of operations to the set. It only
   568  // succeeds when all operations can be applied. No changes are made if it fails.
   569  //
   570  // On failure, it may return an error (retries are hopeless) or it may return
   571  // a channel that can be waited on before attempting again.
   572  func (s *Set) ExecuteOps(ctx context.Context, ops []linux.Sembuf, creds *auth.Credentials, pid int32) (chan struct{}, int32, error) {
   573  	s.mu.Lock()
   574  	defer s.mu.Unlock()
   575  
   576  	// Did it race with a removal operation?
   577  	if s.dead {
   578  		return nil, 0, syserror.EIDRM
   579  	}
   580  
   581  	// Validate the operations.
   582  	readOnly := true
   583  	for _, op := range ops {
   584  		if s.findSem(int32(op.SemNum)) == nil {
   585  			return nil, 0, linuxerr.EFBIG
   586  		}
   587  		if op.SemOp != 0 {
   588  			readOnly = false
   589  		}
   590  	}
   591  
   592  	if !s.checkPerms(creds, fs.PermMask{Read: readOnly, Write: !readOnly}) {
   593  		return nil, 0, linuxerr.EACCES
   594  	}
   595  
   596  	ch, num, err := s.executeOps(ctx, ops, pid)
   597  	if err != nil {
   598  		return nil, 0, err
   599  	}
   600  	return ch, num, nil
   601  }
   602  
   603  func (s *Set) executeOps(ctx context.Context, ops []linux.Sembuf, pid int32) (chan struct{}, int32, error) {
   604  	// Changes to semaphores go to this slice temporarily until they all succeed.
   605  	tmpVals := make([]int16, len(s.sems))
   606  	for i := range s.sems {
   607  		tmpVals[i] = s.sems[i].value
   608  	}
   609  
   610  	for _, op := range ops {
   611  		sem := &s.sems[op.SemNum]
   612  		if op.SemOp == 0 {
   613  			// Handle 'wait for zero' operation.
   614  			if tmpVals[op.SemNum] != 0 {
   615  				// Semaphore isn't 0, must wait.
   616  				if op.SemFlg&linux.IPC_NOWAIT != 0 {
   617  					return nil, 0, syserror.ErrWouldBlock
   618  				}
   619  
   620  				w := newWaiter(op.SemOp)
   621  				sem.waiters.PushBack(w)
   622  				return w.ch, int32(op.SemNum), nil
   623  			}
   624  		} else {
   625  			if op.SemOp < 0 {
   626  				// Handle 'wait' operation.
   627  				if -op.SemOp > valueMax {
   628  					return nil, 0, syserror.ERANGE
   629  				}
   630  				if -op.SemOp > tmpVals[op.SemNum] {
   631  					// Not enough resources, must wait.
   632  					if op.SemFlg&linux.IPC_NOWAIT != 0 {
   633  						return nil, 0, syserror.ErrWouldBlock
   634  					}
   635  
   636  					w := newWaiter(op.SemOp)
   637  					sem.waiters.PushBack(w)
   638  					return w.ch, int32(op.SemNum), nil
   639  				}
   640  			} else {
   641  				// op.SemOp > 0: Handle 'signal' operation.
   642  				if tmpVals[op.SemNum] > valueMax-op.SemOp {
   643  					return nil, 0, syserror.ERANGE
   644  				}
   645  			}
   646  
   647  			tmpVals[op.SemNum] += op.SemOp
   648  		}
   649  	}
   650  
   651  	// All operations succeeded, apply them.
   652  	// TODO(github.com/SagerNet/issue/137): handle undo operations.
   653  	for i, v := range tmpVals {
   654  		s.sems[i].value = v
   655  		s.sems[i].wakeWaiters()
   656  		s.sems[i].pid = pid
   657  	}
   658  	s.opTime = ktime.NowFromContext(ctx)
   659  	return nil, 0, nil
   660  }
   661  
   662  // AbortWait notifies that a waiter is giving up and will not wait on the
   663  // channel anymore.
   664  func (s *Set) AbortWait(num int32, ch chan struct{}) {
   665  	s.mu.Lock()
   666  	defer s.mu.Unlock()
   667  
   668  	sem := &s.sems[num]
   669  	for w := sem.waiters.Front(); w != nil; w = w.Next() {
   670  		if w.ch == ch {
   671  			sem.waiters.Remove(w)
   672  			return
   673  		}
   674  	}
   675  	// Waiter may not be found in case it raced with wakeWaiters().
   676  }
   677  
   678  func (s *Set) checkCredentials(creds *auth.Credentials) bool {
   679  	return s.owner.UID == creds.EffectiveKUID ||
   680  		s.owner.GID == creds.EffectiveKGID ||
   681  		s.creator.UID == creds.EffectiveKUID ||
   682  		s.creator.GID == creds.EffectiveKGID
   683  }
   684  
   685  func (s *Set) checkCapability(creds *auth.Credentials) bool {
   686  	return creds.HasCapabilityIn(linux.CAP_IPC_OWNER, s.registry.userNS) && creds.UserNamespace.MapFromKUID(s.owner.UID).Ok()
   687  }
   688  
   689  func (s *Set) checkPerms(creds *auth.Credentials, reqPerms fs.PermMask) bool {
   690  	// Are we owner, or in group, or other?
   691  	p := s.perms.Other
   692  	if s.owner.UID == creds.EffectiveKUID {
   693  		p = s.perms.User
   694  	} else if creds.InGroup(s.owner.GID) {
   695  		p = s.perms.Group
   696  	}
   697  
   698  	// Are permissions satisfied without capability checks?
   699  	if p.SupersetOf(reqPerms) {
   700  		return true
   701  	}
   702  
   703  	return s.checkCapability(creds)
   704  }
   705  
   706  // destroy destroys the set.
   707  //
   708  // Preconditions: Caller must hold 's.mu'.
   709  func (s *Set) destroy() {
   710  	// Notify all waiters. They will fail on the next attempt to execute
   711  	// operations and return error.
   712  	s.dead = true
   713  	for _, s := range s.sems {
   714  		for w := s.waiters.Front(); w != nil; w = w.Next() {
   715  			w.ch <- struct{}{}
   716  		}
   717  		s.waiters.Reset()
   718  	}
   719  }
   720  
   721  func abs(val int16) int16 {
   722  	if val < 0 {
   723  		return -val
   724  	}
   725  	return val
   726  }
   727  
   728  // wakeWaiters goes over all waiters and checks which of them can be notified.
   729  func (s *sem) wakeWaiters() {
   730  	// Note that this will release all waiters waiting for 0 too.
   731  	for w := s.waiters.Front(); w != nil; {
   732  		if s.value < abs(w.value) {
   733  			// Still blocked, skip it.
   734  			w = w.Next()
   735  			continue
   736  		}
   737  		w.ch <- struct{}{}
   738  		old := w
   739  		w = w.Next()
   740  		s.waiters.Remove(old)
   741  	}
   742  }
   743  
   744  func newWaiter(val int16) *waiter {
   745  	return &waiter{
   746  		value: val,
   747  		ch:    make(chan struct{}, 1),
   748  	}
   749  }