gvisor.dev/gvisor@v0.0.0-20240520182842-f9d4d51c7e0f/pkg/sentry/kernel/auth/id.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 auth
    16  
    17  import (
    18  	"math"
    19  )
    20  
    21  // UID is a user ID in an unspecified user namespace.
    22  //
    23  // +marshal
    24  type UID uint32
    25  
    26  // GID is a group ID in an unspecified user namespace.
    27  //
    28  // +marshal slice:GIDSlice
    29  type GID uint32
    30  
    31  // In the root user namespace, user/group IDs have a 1-to-1 relationship with
    32  // the users/groups they represent. In other user namespaces, this is not the
    33  // case; for example, two different unmapped users may both "have" the overflow
    34  // UID. This means that it is generally only valid to compare user and group
    35  // IDs in the root user namespace. We assign distinct types, KUID/KGID, to such
    36  // IDs to emphasize this distinction. ("k" is for "key", as in "unique key".
    37  // Linux also uses the prefix "k", but I think they mean "kernel".)
    38  
    39  // KUID is a user ID in the root user namespace.
    40  type KUID uint32
    41  
    42  // KGID is a group ID in the root user namespace.
    43  type KGID uint32
    44  
    45  const (
    46  	// NoID is uint32(-1). -1 is consistently used as a special value, in Linux
    47  	// and by extension in the auth package, to mean "no ID":
    48  	//
    49  	//	- ID mapping returns -1 if the ID is not mapped.
    50  	//
    51  	//	- Most set*id() syscalls accept -1 to mean "do not change this ID".
    52  	NoID = math.MaxUint32
    53  
    54  	// OverflowUID is the default value of /proc/sys/kernel/overflowuid. The
    55  	// "overflow UID" is usually [1] used when translating a user ID between
    56  	// namespaces fails because the ID is not mapped. (We implement this
    57  	// file as read-only, so the overflow UID is constant.)
    58  	//
    59  	// [1] "There is one notable case where unmapped user and group IDs are not
    60  	// converted to the corresponding overflow ID value. When viewing a uid_map
    61  	// or gid_map file in which there is no mapping for the second field, that
    62  	// field is displayed as 4294967295 (-1 as an unsigned integer);" -
    63  	// user_namespaces(7)
    64  	OverflowUID = UID(65534)
    65  
    66  	// OverflowGID is the group equivalent to OverflowUID.
    67  	OverflowGID = GID(65534)
    68  
    69  	// NobodyKUID is the user ID usually reserved for the least privileged user
    70  	// "nobody".
    71  	NobodyKUID = KUID(65534)
    72  
    73  	// NobodyKGID is the group equivalent to NobodyKUID.
    74  	NobodyKGID = KGID(65534)
    75  
    76  	// RootKUID is the user ID usually used for the most privileged user "root".
    77  	RootKUID = KUID(0)
    78  
    79  	// RootKGID is the group equivalent to RootKUID.
    80  	RootKGID = KGID(0)
    81  
    82  	// RootUID is the root user.
    83  	RootUID = UID(0)
    84  
    85  	// RootGID is the root group.
    86  	RootGID = GID(0)
    87  )
    88  
    89  // Ok returns true if uid is not -1.
    90  func (uid UID) Ok() bool {
    91  	return uid != NoID
    92  }
    93  
    94  // Ok returns true if gid is not -1.
    95  func (gid GID) Ok() bool {
    96  	return gid != NoID
    97  }
    98  
    99  // Ok returns true if kuid is not -1.
   100  func (kuid KUID) Ok() bool {
   101  	return kuid != NoID
   102  }
   103  
   104  // Ok returns true if kgid is not -1.
   105  func (kgid KGID) Ok() bool {
   106  	return kgid != NoID
   107  }
   108  
   109  // OrOverflow returns uid if it is valid and the overflow UID otherwise.
   110  func (uid UID) OrOverflow() UID {
   111  	if uid.Ok() {
   112  		return uid
   113  	}
   114  	return OverflowUID
   115  }
   116  
   117  // OrOverflow returns gid if it is valid and the overflow GID otherwise.
   118  func (gid GID) OrOverflow() GID {
   119  	if gid.Ok() {
   120  		return gid
   121  	}
   122  	return OverflowGID
   123  }
   124  
   125  // In translates kuid into user namespace ns. If kuid is not mapped in ns, In
   126  // returns NoID.
   127  func (kuid KUID) In(ns *UserNamespace) UID {
   128  	return ns.MapFromKUID(kuid)
   129  }
   130  
   131  // In translates kgid into user namespace ns. If kgid is not mapped in ns, In
   132  // returns NoID.
   133  func (kgid KGID) In(ns *UserNamespace) GID {
   134  	return ns.MapFromKGID(kgid)
   135  }