Provided by: manpages-sv_4.24.0-2_all bug

NAMN

       user_namespaces — översikt över Linux användarnamnrymder

BESKRIVNING

       För en översikt över namnrymder, se namespaces(7).

       Användarnamnrymder  isolerar  säkerhetsrelaterade  identifierare  och attribut, mer exakt,
       användar-ID:n och grupp-ID:n (se credentials(7)), rotkatalogen,  nycklar  (se  keyring(7))
       och  förmågor  (se  capabilities(7)).  En  process användar- och grupp-ID:n kan vara olika
       inuti och utanför  en  användarnamnrymd.  I  synnerhet  kan  en  process  ha  ett  normalt
       oprivilegierat  användar-ID  utanför  en  användarnamnrymd  medan  den  på  samma gång har
       användar-ID:t 0 inuti namnrymden; med andra ord, processen  har  fullständiga  rättigheter
       vid  åtgärder  inuti  användarnamnrymden,  men  är  oprivilegierad  vid  åtgärder  utanför
       namnrymden.

   Nästade namnrymder, medlemskap i namnrymder
       Användarnamnrymder kan nästas; det vill säga, varje användarnamnrymd — utom  den  initiala
       (”rot-”)namnrymden  —  har  en  föräldraanvändarnamnrymd,  och  kan  ha  noll  eller flera
       barnanvändarnamnrymder. Föräldraanvändarnamnrymden är användarnamnrymden för processen som
       skapar  användarnamnrymden  via  ett  anrop  av  unshare(2)  eller  clone(2)  med  flaggan
       CLONE_NEWUSER.

       Kärnan lägger (från Linux 3.11) en gräns på  32  nästade  nivåer  med  användarnamnrymder.
       Anrop  av  unshare(2)  eller  clone(2) som annars skulle orsaka att denna gräns överskrids
       misslyckas med felet EUSERS.

       Varje process är medlem i exakt en användarnamnrymd. En process  som  skapas  via  fork(2)
       eller  clone(2)  utan  flaggan  CLONE_NEWUSER  är medlem av samma användarnamnrymd som sin
       förälder. En enkeltrådad process kan gå in i en annan användarnamnrymd med setns(2) om den
       har  CAP_SYS_ADMIN i den namnrymden; när den gör det får den en fullständig uppsättning av
       förmågor i den namnrymden.

       Ett anrop av clone(2) eller unshare(2) med flaggan CLONE_NEWUSER gör den nya barnprocessen
       (för  clone(2))  eller anroparen (för unshare(2)) medlem av den nya användarnamnrymden som
       skapas av anropet.

       Åtgärden NS_GET_PARENT till ioctl(2) kan  användas  för  att  upptäcka  föräldrarelationen
       mellan användarnamnrymder; se ioctl_ns(2).

       En  uppgift som ändrar ett av sina effektiva ID:n kommer ha sin dumpbarhet återställd till
       värdet  i  /proc/sys/fs/suid_dumpable.  Detta  kan  påverka  ägandet  av  proc-filer   för
       barnprocesser  och kan alltså orsaka att föräldern kommer att sakna rättigheter att skriva
       till avbildningsfiler för barnprocesser som kör i en ny användarnamnrymd. I dessa fall kan
       man  genom  att göra processen dumpbar med PR_SET_DUMPABLE i ett anrop av prctl(2) före en
       barnprocess skapas i en ny användarnamnrymd åtgärda detta problem. Se prctl82) och proc(5)
       för detaljer om hur ägarskap påverkas.

   Förmågor
       Barnprocesserna   som  skapas  med  clone(2)  med  flaggan  CLONE_NEWUSER  börjar  med  en
       fullständig uppsättning av förmågor i den nya användarnamnrymden. Likadant får en  process
       som   skapar   en  ny  användarnamnrymd  med  unshare(2)  eller  går  in  i  en  befintlig
       användarnamnrymd med setns(2) en fullständig uppsättning rättigheter i den  namnrymden.  Å
       andra  sidan  har  den  processen  inga  förmågor  i  förälderns (i fallet clone(2)) eller
       tidigare (i fallet unshare(2)  och  setns(2))  användarnamnrymd,  även  om  root-anvädaren
       skapade  eller  gick  in  i  den  nya  namnrymden  (d.v.s., en process med användar-ID 0 i
       rotnamnrymden).

       Observera att ett anrop av execve(2) kommer göra att processens förmågor räknas om på  det
       vanliga  sättet  (se  capabilities(7)).  Alltså,  om inte processen har användar-ID 0 inom
       namnrymden, eller den körbara filen har en ärvbar förmågemask  som  inte  är  tom,  kommer
       processen  förlora  alla  förmågor. Se diskussionen om användar- och grupp-ID-avbildningar
       nedan.

       Ett anrop av clone(2) eller unshare(2)  med  flaggan  CLONE_NEWUSER  eller  ett  anrop  av
       setns(2)   som   flyttar  anroparen  in  i  en  annan  användarnamnrymd  sätter  flaggorna
       ”securebits” (se capabilities(7)) till sitt standardvärde (alla flaggor avslagna) i barnet
       (för  clone(2))  eller  anroparen  (för unshare(2) eller setns(2)). Observera att eftersom
       anroparen inte längre  har  förmågor  i  sin  originalanvändarnamnrymd  efter  anropet  av
       setns(2) är det inte möjligt för en process att återställa sina flaggor ”securebits” medan
       den behåller sitt medlemskap i användarnamnrymden genom att använda ett par  av  anrop  av
       setns(2)  för  att  flytta  till  en  annan  användarnamnrymd och sedan återvända till sin
       originalanvändarnamnrymd.

       Reglerna för att avgöra  huruvida  en  process  har  en  förmåga  eller  inte  i  en  viss
       användarnamnrymd är som följer:

       •  En  process har en förmåga inuti en användarnamnrymd om den är medlem av den namnrymden
          och den har förmågan i sin effektiva förmågemängd. En process kan  få  förmågor  i  sin
          effektiva   förmågemängd   på   olika   sätt.   Till   exempel   kan   den   köra   ett
          sätt-användar-ID-program eller en körbar fil associerad med filförmågor.  Dessutom  kan
          en  process  få förmågor via effekten av clone(2), unshare(2) eller setns(2), som redan
          beskrivits.

       •  Om en process har en förmåga  i en användarnamnrymd, då har den  den  förmågan  i  alla
          barn- (och mer avlägsna avkomme-)namnrymder också.

       •  När  en användarnamnrymd skapas sparar kärnan det effektiva användar-ID:t för processen
          som skapar den som varandes ”ägaren” till namnrymden. En process som  bor  i  föräldern
          till  användarnamnrymden  och  vars  effektiva  användar-ID  stämmer  med  ägaren  till
          namnrymden har alla förmågor i namnrymden. Tack vare  föregående  regel  har  processen
          alla   förmågor   i   alla   mer  avlägsna  avkommeanvändarnamnrymder  också.  Åtgärden
          NS_GET_OWNER_UID  till  ioctl(2)  kan  användas  för  att  upptäcka   användar-ID   för
          namnrymdens ägare; se ioctl_ns(2).

   Effekten av förmågor inom en användarnamnrymd
       Att  ha  en förmåga inuti en användarnamnrymd tillåter en process att utföra åtgärder (som
       kräver privilegier) endast på resurser som styrs av den namnrymden. Med andra ord, att  ha
       en förmåga i en användarnamnrymd tillåter en process att utföra privilegierade åtgärder på
       resurser som  styrs  av  (icke  användar-)namnrymder  som  ägs  av  (är  associerade  med)
       användarnamnrymden (se nästa underavdelning).

       Däremot  finns  det  många  privilegierade  åtgärder  som  påverkar  resurser  som inte är
       associerade  med  någon  namnrymdstyp,  till  exempel,  att  ändra  systemtiden   (d.v.s.,
       kalendertiden)   (som  styrs  av  CAP_SYS_TIME),  att  ladda  kärnmoduler  (som  styrs  av
       CAP_SYS_MODULE) och att skapa en enhet (som styrs av CAP_MKNOD).  Endast  en  process  med
       privilegier i den initiala användarnamnrymden kan utföra sådana åtgärder.

       Att hålla CAP_SYS_ADMIN inom användarnamnrymden som äger en process monteringsnamnrymd gör
       att den processen kan skapa bindmonteringar och montera följande typer av filsystem:

           •  /proc (från Linux 3.8)
           •  /sys (från Linux 3.8)
           •  devpts (från Linux 3.9)
           •  tmpfs(5)  (från Linux 3.9)
           •  ramfs (från Linux 3.9)
           •  mqueue (från Linux 3.9)
           •  bpf (från Linux 4.4)
           •  overlayfs (från Linux 5.11)

       Att hålla CAP_SYS_ADMIN inom användarnamnrymden som äger en  process  cgroup-namnrymd  gör
       (från  Linux 4.6) att den processen kan montera filsystemet cgroup version 2 och namngivna
       hierarkier av filsystemet cgroup verson 1 (d.v.s., cgroup-filsystem monterade med  flaggan
       "none,name=").

       Att hålla CAP_SYS_ADMIN inom användarnamnrymden som äger en process PID-namnrymd gör (från
       Linux 3.8) att den processen kan montera filsystemet /proc.

       Observera dock att montering av blockbaserade filsystem endast kan göras av en process som
       håller CAP_SYS_ADMIN i den initiala användarnamnrymden.

   Interaktion mellan användarnamnrymder och andra typer av namnrymder
       Med  början  från Linux 3.8 kan oprivilegierade processer skapa användarnamnrymder, och de
       andra typerna av namnrymder kan  skapas  med  bara  förmågan  CAP_SYS_ADMIN  i  anroparens
       användarnamnrymd.

       När  en  annan  namnrymd  än  en  användarnamnrymd  skapas  ägs  den av användarnamnrymden
       processen som skapade  den  var  en  medlem  i  vid  tidpunkten  då  namnrymden  skapades.
       Privilegierade  åtgärder  på  resurser  som  styrs  av en icke-användarnamnrymd kräver att
       processen   har   de   nödvändiga   förmågorna   i   användarnamnrymden   som   äger   den
       icke-användarnamnrymden.

       Om  CLONE_NEWUSER  anges  tillsammans  med andra flaggor CLONE_NEW* i ett enskilt anrop av
       clone(2) eller unshare(2) garanteras det att användarnamnrymden skapas  först  vilket  ger
       barnet  (clone(2)) eller anroparen (unshare(2)) privilegier över de andra namnrymderna som
       skapas av anropet. Det är alltså möjligt för en oprivilegierad  anropare  att  ange  denna
       kombination av flaggor.

       När  en  ny  namnrymd  (annan än en användarnamnrymd) skapas via clone(2) eller unshare(2)
       registrerar kärnan användarnamnrymden för processen som skapar den som ägare till den  nya
       namnrymden.  (Denna  koppling kan inte ändras.) När en process i den nya namnrymden senare
       utför privilegierade åtgärder som verkar  på  globala  resurser  isolerade  av  namnrymden
       utförs  rättighetskontrollerna  enligt processens förmågor i användarnamnrymden som kärnan
       associerade med den nya namnrymden. Till exempel, antag  att  en  process  försöker  ändra
       värdnamnet  (sethostname(2)),  en  resurs som styrs av UTS-namnrymden. I detta fall kommer
       kärnan avgöra vilken användarnamnrymd som äger processens  UTS-namnrymd,  och  kontrollera
       huruvida processen har den nödvändiga förmågan (CAP_SYS_ADMIN) i den användarnamnrymden.

       ioctl(2)-åtgärden  NS_GET_USERNS kan användas för att hitta användarnamnrymden som äger en
       icke-användarnamnrymd; se ioctl_ns(2).

   Användar- och grupp-ID-avbildningar: uid_map och gid_map
       När  en  användarnamnrymd  skapas  börjar  den  utan  någon  avbildning  av  användar-ID:n
       (grupp-ID:n)    till    förälderns   användarnamnrymd.   Filerna   /proc/pid/uid_map   och
       /proc/pid/gid_map (tillgängliga från Linux 3.5) visar  avbildningarna  för  användar-  och
       grupp-ID:n  inuti användarnamnrymden för processen pid. Dessa filer kan läsas för att visa
       avbildningarna i en  användarnamnrymd  och  skrivas  till  (en  gång)  för  att  definiera
       avbildningarna.

       Beskrivningen  i  följande  stycken  förklarar  detaljerna  för  uid_map; gid_map är exakt
       likadan, med varje förekomst av ”användar-ID” ersatt med ”grupp-ID”.

       Filen uid_map visar avbildningen av användar-ID:n från  användarnamnrymden  för  processen
       som  öppnade  uid_map  (men  se  en  avvikelse  från denna punkt nedan). Med andra ord kan
       potentiellt processer som finns i olika användarnamnrymder se olika värden  när  de  läser
       från  en viss uid_map-fil, beroende på användar-ID-avbildningarna för användarnamnrymderna
       för de läsande processerna.

       Varje rad i filen uid_map anger en 1-till-1-avbildning av ett intervall av  sammanhängande
       användar-ID:n  mellan  två  användarnamnrymder.  (När  en användarnamnrymd först skapas är
       denna fil tom.) Specifikationen på varje rad har formen tre tal avgränsade av  mellanslag.
       De   första   två   talen   anger   det   första   användar-ID:t   i  vardera  av  de  två
       användarnamnrymderna. Det tredje talet anger längden på  det  avbildade  intervallet.  Mer
       exakt tolkas fälten som följer:

       (1)  Början av intervallet av användar-ID:n i processen pids användarnamnrymd.

       (2)  Början på intervallet av användar-ID:n till vilka användar-ID:n som anges av fält ett
            avbildas. Hur fält två tolkas beror på huruvida processen  som  öppnade  uid_map  och
            processen pid finns i samma användarnamnrymd, som följer:

            (a)  Om  de  två  processerna finns i olika användarnamnrymder: fält två är början på
                 ett intervall av användar-ID:n i användarnamnrymden för  processen  som  öppnade
                 uid_map.

            (b)  Om  de  två  processerna  finns  i samma användarnamnrymd: fält två är början på
                 intervallet av användar-ID:n i process pids föräldraanvändarnamnrymd. Detta  gör
                 att   den   som   öppnar   uid_map   (det   vanliga  fallet  här  är  att  öppna
                 /proc/self/uid_map) kan se avbildningen av användar-ID:n in i användarnamnrymden
                 för processen som skapade denna användarnamnrymd.

       (3)  Längden    på   intervallet   av   användar-ID:n   som   avbildas   mellan   de   två
            användarnamnrymderna.

       Systemanrop som returnerar användar-ID:n (grupp-ID:n) — till exempel getuid(2), getgid(2),
       och  kreditivfälten  i  posten  som  returneras  av  stat(2)  —  returnerar  användar-ID:t
       (grupp-ID:t) avbildat in i anroparens användarnamnrymd.

       När en process begär tillgång till en fil avbildas dess användar- och grupp-ID:n in i  den
       initiala användarnamnrymden i syfte att kontrollera rättigheterna och tilldela ID:n när en
       fil skapas. När en process hämtar filens användar- och  grupp-ID:n  via  stat(2)  avbildas
       ID:erna  i  den  andra  riktningen, för att skapa värden relativt processens användar- och
       grupp-ID-avbildningar.

       Den initiala användarnamnrymden har ingen föräldranamnrymd, men  för  konsistensens  skull
       tillhandahåller   kärnan   tomfiler   för  användar-  och  grupp-ID-avbildningar  för  den
       namnrymden. Tittar man på filen uid_map (gid_map är likadan) från ett skal i den  initiala
       namnrymden ser man:

           $ cat /proc/$$/uid_map
                    0          0 4294967295

       This  mapping  tells  us  that the range starting at user ID 0 in this namespace maps to a
       range starting at 0 in the (nonexistent) parent namespace, and the length of the range  is
       the  largest  32-bit unsigned integer. This leaves 4294967295 (the 32-bit signed -1 value)
       unmapped. This is deliberate: (uid_t) -1 is used in several interfaces (e.g., setreuid(2))
       as a way to specify "no user ID". Leaving (uid_t) -1 unmapped and unusable guarantees that
       there will be no confusion when using these interfaces.

   Att definiera användar- och grupp-ID-avbildningar: att skriva till uid_map och gid_map
       Efter att en ny användarnamnrymd skapats  kan  filen  uid_map  för  en  av  processerna  i
       namnrymden  skrivas till en gång för att definiera avbildningen av användar-ID:n i den nya
       användarnamnrymden. Ett försök att skriva  mer  än  en  gång  till  en  uid_map-fil  i  en
       användarnamnrymd misslyckas med felet EPERM. Motsvarande regler gäller för gid_map-filer.

       Raderna som skrivs till uid_map (gid_map) måste lyda följande giltighetsregler:

       •  De tre fälten måste vara giltiga tal, och det sista fältet måste vara större än 0.

       •  Rader avslutas av nyradstecken.

       •  Det  finns  en  gräns  på antalet rader i filen. I Linux 4.14 och tidigare sattes denna
          gräns (godtyckligt) till 5 rader. Från Linux 4.15 är gränsen 340 rader. Dessutom  måste
          antalet byte som skrivs till filen vara mindre än systemets sidstorlek, och skrivningen
          måste göras från början av filen (d.v.s., lseek(2) och pwrite(2) kan inte användas  för
          att skriva till nollskilda avstånd in i filen).

       •  Intervallet av användar-ID:n (grupp-ID:n) som anges på varje rad får inte överlappa med
          intervallerna på några andra rader. I den  ursprungliga  implementationen  (Linux  3.8)
          uppfylldes  detta  krav av en enkel implementation som lade till det ytterligare kravet
          att värdena i både fält 1 och fält 2 av följande rader måste vara i  stigande  numerisk
          ordning,  vilket  förhindrade  några eljest giltiga avbildningar från att skapas. Linux
          3.9 och senare fixar denna begränsning, och  tillåter  alla  giltiga  uppsättningar  av
          avbildningar som inte överlappar.

       •  Åtminstone en rad måste skrivas till filen.

       Skrivningar som bryter mot ovanstående regler misslyckas med felet EINVAL.

       För att en process skall kunna skriva till filen /procpid/uid_map (/procpid/gid_map) måste
       alla följande rättighetskrav vara uppfyllda:

       •  Den skrivande processen måste ha förmågan  CAP_SETUID  (CAP_SETGID)  i  processen  pids
          användarnamnrymd.

       •  Den skrivande processen måste antingen finnas i namnrymden för process pid eller finnas
          i föräldraanvändarnamnrymden till process pid.

       •  De  avbildade  användar-ID:na  (grupp-ID:na)  måste  i  sin  tur  ha  en  avbildning  i
          föräldraanvändarnamnrymden.

       •  Om man uppdaterar /proc/pid/uid_map för att skapa en avbildning som avbildar till UID 0
          i föräldranamnrymden måste en av de följande vara sann:

          (a)  om den skrivande processen finns i föräldraanvändarnamnrymden,  då  måste  den  ha
               förmågan CAP_SETFCAP i den användarnamnrymden; eller

          (b)  om  den skrivande processen finns i barnanvändarnamnrymden, då måste processen som
               skapade användarnamnrymden ha haft förmågan CAP_SETFCAP när namnrymden skapades.

          Denna regel har funnits från Linux 5.12.  Den  eliminerar  en  tidigare  säkerhetsbrist
          varigenom  en UID 0-process som saknar förmågan CAP_SETFCAP vilken behövs för att skapa
          en binär med namnrymdsfilförmågor (så som det beskrivs i  capabilities(7))  ändå  kunde
          skapa en sådan binär genom följande steg:

          (1)  Skapa  en  ny användarnamnrymd med identitetsavbildningen (d.v.s., AID 0 i den nya
               användarnamnrymden avbildas på AID 0 i föräldranamnrymden),  så  att  AID  0  båda
               namnrymderna är ekvivalent med samma root-användar-ID.

          (2)  Eftersom  barnprocessen  har  förmågan  CAP_SETFCAP  kunde  den skapa en binär med
               namnrymdsfilförmågor som sedan skulle  vara  verkningsfulla  i  föräldranamnrymden
               (eftersom root-användar-ID:t är desamma i de två namnrymderna).

       •  En av följande två fall gäller:

          (a)  Antingen   har   den   skrivande  processen  förmågan  CAP_SETUID  (CAP_SETGID)  i
               föräldraanvändarnamnrymden.

               •  Inga ytterligare begränsningar gäller: processen  kan  göra  avbildningar  till
                  godtyckliga användar-ID:n (grupp-ID:n) i föräldraanvändarnamnrymden.

          (b)  Eller i annat fall gäller alla följande beskrivningar:

               •  Data  som skrivs till uid_map (gid_map) måste bestå av en enda rad som avbildar
                  den    skrivande    processens    effektiva    användar-ID     (grupp-ID)     i
                  föräldraanvändarnamnrymden     till     ett     användar-ID     (grupp-ID)    i
                  användarnamnrymden.

               •  Den skrivande processen måste ha samma effektiva användar-ID som processen  som
                  skapade användarnamnrymden.

               •  När  det  gäller  gid_map  måste först användning av systemanropet setgroups(2)
                  nekas genom att skriva "deny" till filen /proc/pid/setgroups  (se  nedan)  före
                  någon skrivning till gid_map.

       Skrivningar som strider mot ovanstående regler misslyckas med felet EPERM.

   Projekt-ID-avbildningar: projid_map
       Liksom    för   användar-   och   grupp-ID-avbildningar   är   det   möjligt   att   skapa
       projekt-ID-avbildningar för användarnamnrymder. (Projekt-ID:n används för  diskkvoter;  se
       setquota(8) och quotactl(2).)

       Projekt-ID-avbildningar  definieras  genom att skriva till filen /proc/pid/projid_map (som
       finns från Linux 3.7).

       Giltighetsreglerna för att skriva till filen /proc/pid/projid_map är som  för  att  skriva
       till filen uid_map; brott mot dessa regler får write(2) att misslyckas med felet EINVAL.

       Rättighetsreglerna för att skriva till filen /proc/pid/projid_map är som följer:

       •  Den skrivande processen måste antingen finnas i namnrymden för process pid eller finnas
          i föräldraanvändarnamnrymden till process pid.

       •  De   avbildade   projekt-ID:na   måste   i    sin    tur    ha    en    avbildning    i
          föräldraanvändarnamnrymden.

       Brott mot dessa regler får write(2) att misslyckas med felet EPERM.

   Interaktion med systemanrop som ändrar process-AID:n eller -GID:n
       I  en  användarnamnrymd  där filen uid_map inte har skrivits kommer systemanrop som ändrar
       användar-ID:n att misslyckas. På liknande sätt, om filen gid_map inte har skrivits  kommer
       systemanrop  som  ändrar  grupp-ID:n att misslyckas. Efter att filerna uid_map och gid_map
       har skrivits kan endast de avbildade värdena användas i systemanrop som  ändrar  användar-
       och grupp-ID:n.

       För   användar-ID:n   inkluderar   de   relevanta  systemanropen  setuid(2),  setfsuid(2),
       setreuid(2)  och  setresuid(2).  För  grupp-ID:n  inkluderar  de  relevanta  systemanropen
       setgid(2), setfsgid(2), setregid(2), setresgid(2) och setgroups(2).

       Att  skriva  "deny" till filen /proc/pid/setgroups före man skriver till /proc/pid/gid_map
       kommer permanent avaktivera setgroups(2) i en användarnamnrymd och tillåta att man skriver
       till /proc/pid/gid_map utan att ha förmågan CAP_SETGID i föräldraanvändarnamnrymden.

   Filen /proc/pid/setgroups
       Filen  /proc/pid/setgroups  visar  strängen  "allow" om processer i användarnamnrymden som
       innehåller process pid får lov att använda systemanropet setgroups(2); den visar "deny" om
       setgroups(2)  inte  tillåts i den användarnamnrymden. Observera att oavsett värdet i filen
       /proc/pid/setgroups (och oavsett processens förmågor) är inte heller setgroups(2) tillåtet
       om inte /proc/pid/gid_map har satts ännu.

       En privilegierad process (en med förmågan CAP_SYS_ADMIN i namnrymden) kan skriva endera av
       strängarna "allow" eller "deny" till denna fil före den skriver en grupp-ID-avbildning för
       denna användarnamnrymd till filen /proc/pid/gid_map. Att skriva strängen "deny" förhindrar
       alla processer i användarnamnrymden från att använda setgroups(2).

       Essensen av begränsningarna som beskrivs i föregående stycke är att det  är  tillåtet  att
       skriva till /proc/pid/setgroups endast så länge som anrop av setgroups(2) är otillåtet för
       att /proc/pid/gid_map inte har satts. Detta säkerställer att en process inte kan  gå  över
       från ett tillstånd där setgroups(2) är tillåtet till ett tillstånd där setgroups(2) nekas;
       en process kan gå över endast från att setgroups(2) är otillåtet till att setgroups(2)  är
       tillåtet.

       Standardvärdet i denna fil i den initiala användarnamnrymden är "allow".

       När  /proc/pid/gid_map har skrivits till (vilket har effekten av att aktivera setgroups(2)
       i användarnamnrymden), är det inte längre möjligt att göra  setgroups(2)  otillåtet  genom
       att skriva "deny" till /proc/pid/setgroups (skrivningen misslyckas med felet EPERM).

       En barnnamnrymd ärver inställningen av /proc/pid/setgroups från sin förälder.

       Om  filen  setgroups  har  värdet  "deny",  då  kan inte senare systemanropet setgroups(2)
       återaktiveras (genom att skriva "allow" till filen) i den användarnamnrymden. (Försök  att
       göra  så  misslyckas  med  felet  EPERM.)  Denna  begränsning  propagerar  ner  till  alla
       barnanvändarnamnrymder till denna användarnamnrymd.

       Filen /proc/pid/setgroups lades till i Linux 3.19, men bakåtporterades till många tidigare
       stabila  kärnserier, eftersom den åtgärdar ett säkerhetsproblem. Problemet rörde filer med
       rättigheter såsom ”rwx---rwx”. Sådana filer ger färre rättigheter till ”gruppen” än de gör
       till  ”övriga”. Detta betyder att genom att släppa grupper med setgroups(2) kan en process
       tillåtas filåtkomst som den inte tidigare hade.  Före  det  fanns  användarnamnrymder  var
       detta  inte  ett  bekymmer,  eftersom  endast  en  privilegierad  process (en med förmågan
       CAP_SETGID) kunde anropa setgroups(2). Dock, med introduktionen av användarnamnrymder blev
       det möjligt för en oprivilegierad process att skapa en ny namnrymd i vilken användaren har
       alla privilegier.  Detta  tillät  sedan  tidigare  oprivilegierade  användare  att  släppa
       grupprivilegier   och   därmed   få   filåtkomst   som   de   inte  tidigare  hade.  Filen
       /proc/pid/setgroups lades till för att åtgärda detta säkerhetsproblem, genom att neka alla
       vägar för en oprivilegierad process att släppa grupper med setgroups(2).

   Oavbildade användar- och grupp-ID:n
       Det  finns  olika  platser  där  ett  oavbildat  användar-ID  (grupp-ID) kan exponeras för
       användarrymden. Till exempel kan den första processen  i  en  ny  användarnamnrymd  anropa
       getuid(2)  innan  en  användar-ID-avbildning  har  definierats för namnrymden. I de flesta
       sådana fall konverteras ett oavbildat användar-ID  till  spillanvändar-ID:t  (grupp-ID:t);
       standardvärdet   på   spillanvändar-ID:t   (grupp-ID:t)   65534).  Se  beskrivningarna  av
       /proc/sys/kernel/overflowuid och /proc/sys/kernel/overflowgid i proc(5).

       Fallen där oavbildade ID:n avbildas på detta sätt inkluderar  systemanrop  som  returnerar
       användar-ID:n   (getuid(2),  getgid(2)  och  liknande),  kreditiv  som  skickas  över  ett
       UNIX-domänsuttag,  kreditiv  som  returneras  av  stat(2),  waitid(2)  och  System  V  IPC
       ”ctl”-åtgärder  IPC_STAT,  kreditiv  som  exponeras  av  /proc/pid/status  och  filerna  i
       /proc/sysvipc/*, kreditiv som returneras via fältet si_uid i den siginfo_t  som  tas  emot
       med  en  signal  (se  sigaction(2)),  kreditiv  som skrivs till processbokföringsfilen (se
       acct(5)) och  kreditiv  som  returneras  via  POSIX  notifieringar  i  meddelandeköer  (se
       mq_notify(3)).

       Det  finns ett nämnvärt fall där oavbildade användar- och grupp-ID:n inte konverteras till
       motsvarande spill-ID-värde. När man betraktar en fil uid_map eller gid_map  i  vilken  det
       inte  finns  någon avbildning för det andra fältet visas det fältet som 4294967295 (-1 som
       ett teckenlöst heltal).

   Åtkomst av filer
       För att avgöra rättigheterna när en oprivilegierad process  söker  tillgång  till  en  fil
       avbildas  processkreditiven  (AID,  GID)  och de aktiva filkreditiven tillbaka till vad de
       skulle  vara  i  den  initiala  användarnamnrymden  och  jämförs  sedan  för  att   avgöra
       rättigheterna  som  processen  har till filen. Detsamma är också sant för andra objekt som
       använder åtkomstmodellen med kreditiv plus rättighetsmasker, såsom System V IPC-objekt.

   Åtgärder med filrelaterade förmågor
       Vissa  förmågor  tillåter  en  process  att  kringgå  olika   begränsningar   som   kärnan
       upprätthåller  när  den  utför åtgärder på filer som ägs av andra användare eller grupper.
       Dessa  förmågor  är:  CAP_CHOWN,  CAP_DAC_OVERRIDE,  CAP_DAC_READ_SEARCH,  CAP_FOWNER  och
       CAP_FSETID.

       Inom  en  användarnamnrymd  tillåter  dessa  förmågor  en  process att kringgå reglerna om
       processen har den relevanta förmågan över filen, vilket betyder:

       •  processen har den relevanta effektiva förmågan i sin användarnamnrymd; och

       •  filens användar-ID och grupp-ID båda har giltiga avbildningar i användarnamnrymden.

       Förmågan CAP_FOWNER behandlas  något  speciellt:  den  tillåter  en  process  att  kringgå
       motsvarande  regler  så  länge  som  åtminstone  filens  användar-ID  har  en avbildning i
       användarnamnrymden (d.v.s., filens grupp-ID behöver inte ha en giltig avbildning).

   Sätt-användar-ID- och sätt-grupp-ID-program
       När en  process  inuti  en  användarnamnrymd  kör  ett  program  som  är  sätt-användar-ID
       (sätt-grupp-ID) ändras processens effektiva användar- (grupp-)ID inuti namnrymden till det
       värde som är avbildat för filens användar- (grupp-)ID. Dock, om antingen filens  användar-
       eller   grupp-ID   inte  har  någon  avbildning  inuti  namnrymden  ignoreras  tyst  biten
       sätt-användar-ID (sätt-grupp-ID):  det  nya  programmet  körs,  men  processens  effektiva
       användar-  (grupp-)ID  lämnas  orört. (Detta avspeglar semantiken hos att köra ett program
       med sätt-användar-ID eller sätt-grupp-ID som bor  på  ett  filsystem  som  monterades  med
       flaggan MS_NOSUID, såsom beskrivs i mount(2).)

   Diverse
       När  en process användar- och grupp-ID:n skickas över ett UNIX-domänsuttag till en process
       i en annan användarnamnrymd (se beskrivningen av SCM_CREDENTIALS i unix(7))  översätts  de
       till  de  motsvarande  värdena  i  enlighet  med  den  mottagande processens användar- och
       grupp-ID-avbildningar.

STANDARDER

       Linux.

NOTERINGAR

       Under åren har det funnits många funktioner som har lagts till till  Linuxkärnan  som  har
       gjorts  tillgängliga  endast till privilegierade användare på grund av deras potential att
       förvirra  sätt-användar-ID-root-program.  I  allmänhet  blir  det   säkert   att   tillåta
       root-användaren  i  en  användarnamnrymd  att  använda  dessa  funktioner  eftersom det är
       omöjligt, så länge man finns i en användarnamnrymd, att få fler privilegier än de  som  en
       användarnamnrymds root-användare har.

   Global root
       Termen  ”global  root”  används  ibland  som  en kortform för användar-ID 0 i den initiala
       användarnamnrymden.

   Tillgänglighet
       Användning av användarnamnrymder kräver en kärna  som  är  konfigurerad  med  alternativet
       CONFIG_USER_NS.  Användarnamnrymder kräver stöd i ett antal undersystem i hela kärnan. När
       ett undersystem som inte stödjs konfigureras i kärnan är det inte möjligt att  konfigurera
       stöd för användarnamnrymder.

       Fram till Linux 3.8 stödde de mest relevanta subsystemen användarnamnrymder, men ett antal
       filsystem  hade  inte  den  nödvändiga  infrastrukturen  för  att  avbilda  användar-  och
       grupp-ID:n    mellan    användarnamnrymder.   Linux   3.9   lade   till   det   nödvändiga
       infrastrukturstödet till många av de återstående  ej  stödda  filsystemen  (Plan  9  (9P),
       Andrew File System (AFS), Ceph, CIFS, CODA, NFS och OCFS2). Linux 3.12 lade till stöd till
       det sista av de ej stödda större filsystemen, XFS.

EXEMPEL

       Nedanstående program är skapat för att möjliggöra experimenterande med användarnamnrymder,
       liksom  även  andra typer av namnrymder. Det skapar namnrymder enligt specifikationen från
       kommandoradsflaggor och kör sedan ett kommando inuti dessa namnrymder.  Kommentarerna  och
       funktionen  usage()  inuti  programmet  ger  den  fullständiga förklaringen av programmet.
       Följande skalsession demonstrerar dess användning.

       Först betraktar vi körtidsmiljön:

           $ uname -rs     # Förutsätter Linux 3.8 eller senare
           Linux 3.8.0
           $ id -u         # Kör som en oprivilegierad användare
           1000
           $ id -g
           1000

       Starta nu ett skal i en ny användar- (-U), monterings- (-m) och PID-  (-p)  namnrymd,  med
       användar-ID (-M) och grupp-ID (-G) 1000 avbildade på 0 inuti användarnamnrymden:

           $ ./userns_child_exec -p -m -U -M '0 1000 1' -G '0 1000 1' bash

       Skalet har PID 1, för att det är den första processen i den nya PID-namnrymden.

           bash$ echo $$
           1

       Att  montera  ett nytt /proc-filsystem och lista alla processerna som är synliga i den nya
       PID-namnrymden visar att skalet inte kan se några processer utanför  PID-namnrymden:

           bash$ mount -t proc proc /proc
           bash$ ps ax
             PID TTY      STAT   TIME COMMAND
               1 pts/3    S      0:00 bash
              22 pts/3    R+     0:00 ps ax

       Inuti  användarnamnrymden  har  skalet  användar-  och  grupp-ID  0,  och  den   kompletta
       uppsättningen av tillåtna och effektiva förmågor:

           bash$ cat /proc/$$/status | egrep '^[UG]id'
           Uid: 0    0    0    0
           Gid: 0    0    0    0
           bash$ cat /proc/$$/status | egrep '^Cap(Prm|Inh|Eff)'
           CapInh:   0000000000000000
           CapPrm:   0000001fffffffff
           CapEff:   0000001fffffffff

   Programkällkod

       /* userns_child_exec.c

          Licensed under GNU General Public License v2 or later

          Skapa en barnprocess som kör ett skalkommando i nya namnrymder;
          låt UID- och GID-avbildningar anges när en användarnamnrymd
          skapas.
       */
       #define _GNU_SOURCE
       #include <err.h>
       #include <sched.h>
       #include <unistd.h>
       #include <stdint.h>
       #include <stdlib.h>
       #include <sys/wait.h>
       #include <signal.h>
       #include <fcntl.h>
       #include <stdio.h>
       #include <string.h>
       #include <limits.h>
       #include <errno.h>

       struct child_args {
           char **argv;        /* Kommando att köras av barnet, med argument */
           int    pipe_fd[2];  /* Rör använt för att synkronisera förälder och barn */
       };

       static int verbose;

       static void
       usage(char *pname)
       {
           fprintf(stderr, "Användning: %s [flaggor] kmd [arg…]\n\n", pname);
           fprintf(stderr, "Skapa en barnprocess som kör ett skalkommando i "
                   "en ny användarnamnrymd,\n"
                   "och eventuellt även andra nya namnrymder.\n\n");
           fprintf(stderr, "Flaggor kan vara:\n\n");
       #define fpe(str) fprintf(stderr, "    %s", str);
           fpe("-i          Ny IPC-namnrymd\n");
           fpe("-m          Ny monteringsnamnrymd\n");
           fpe("-n          Ny nätverksnamnrymd\n");
           fpe("-p          Ny PID-namnrymd\n");
           fpe("-u          Ny UTS-namnrymd\n");
           fpe("-U          Ny användarnamnrymd\n");
           fpe("-M uid_map  Ange AID-avbildning för användarnamnrymden\n");
           fpe("-G gid_map  Ange GID-avbildning för användarnamnrymden\n");
           fpe("-z          Avbilda användar-AID och -GID till 0 i användarnamnrymden\n");
           fpe("            (ekvivalent med: -M '0 <aid> 1' -G '0 <gid> 1')\n");
           fpe("-v          Visa utförliga meddelanden\n");
           fpe("\n");
           fpe("Om -z, -M eller -G anges är -U nödvändigt.\n");
           fpe("Det är inte tillåtet att ange både -z och någon av -M eller -G.\n");
           fpe("\n");
           fpe("Avbildningssträngar för -M och -G består av poster på formen:\n");
           fpe("\n");
           fpe("    ID-inuti-nr   ID-utanför-nr   längd\n");
           fpe("\n");
           fpe("En avbildningssträng kan innehålla flera poster, separerade"
               " av komman;\n");
           fpe("kommatecknen ersätts med nyrader före skrivning"
               " till avbildningsfiler.\n");

           exit(EXIT_FAILURE);
       }

       /* Uppdatera avbildningsfilen 'map_fil', med värdena som ges i
          'avbildning', en sträng som definierar en AID- eller GID-avbildning.
          En AID- eller GID-avbildning består av en eller flera nyradsavgränsade poster
          på formen:

              ID_inuti-nr    ID-utanför-nr   längd

          Att begära att användaren skall ge en sträng som innehåller nyrader är
          naturligtvis opraktiskt för kommandoradsanvändning. Därför tillåter vi
          användningen av komman för att avgränsa poster i denna sträng, och
          ersätter dem med nyrader före vi skriver strängen till filen. */"

       static void
       update_map(char *mapping, char *map_file)
       {
           int fd;
           size_t map_len;     /* Längden på \[aq]avbildning\[aq] */

           /* Ersätt kommatecken i avbildningssträngar med nyrader. */

           map_len = strlen(mapping);
           for (size_t j = 0; j < map_len; j++)
               if (mapping[j] == ',')
                   mapping[j] = '\n';

           fd = open(map_file, O_RDWR);
           if (fd == -1) {
               fprintf(stderr, "FEL: open %s: %s\n", map_file,
                       strerror(errno));
               exit(EXIT_FAILURE);
           }

           if (write(fd, mapping, map_len) != map_len) {
               fprintf(stderr, "FEL: write %s: %s\n", map_file,
                       strerror(errno));
               exit(EXIT_FAILURE);
           }

           close(fd);
       }

       /* Linux 3.19 gjorde en ändring av hanteringen av setgroups(2) och filen
          'gid_map' för att åtgärda ett säkerhetsproblem. Problemet tillät
          *oprivilegierade* användare att nyttja användarnamnrymder för att släppa
          grupper. Följden av ändringarna i 3.19 är att för att uppdatera filen
          'gid_maps' måste först användning av systemanropet setgroups()
          i denna användarnamnrymd avaktiveras genom att skriva "deny" till en
          av filerna /proc/PID/setgroups för denna namnrymd. Det är syftet med
          följande funktion. */

       static void
       proc_setgroups_write(pid_t child_pid, char *str)
       {
           char setgroups_path[PATH_MAX];
           int fd;

           snprintf(setgroups_path, PATH_MAX, "/proc/%jd/setgroups",
                   (intmax_t) child_pid);

           fd = open(setgroups_path, O_RDWR);
           if (fd == -1) {

               /* Vi kan vara på ett system som inte stödjer /proc/PID/setgroups.
                  I det fallet kommer filen inte att finnas, och systemet kommer
                  inte att påtvinga begränsningarna som Linux 3.19 lade till. Det
                  är bra så: vi behöver inte göra något för att tillåta att
                  'gid_map' uppdateras.

                  Dock, om felet från open() var något annat än felet ENOENT
                  som förväntas i det fallet, tala om det för användaren. */

               if (errno != ENOENT)
                   fprintf(stderr, "FEL: open %s: %s\n", setgroups_path,
                       strerror(errno));
               return;
           }

           if (write(fd, str, strlen(str)) == -1)
               fprintf(stderr, "FEL: write %s: %s\n", setgroups_path,
                   strerror(errno));

           close(fd);
       }

       static int              /* Startfunktion för klonat barn */
       childFunc(void *arg)
       {
           struct child_args *args = arg;
           char ch;

           /* Vänta tills föräldern har uppdaterat AID- och GID-avbildningarna.
              Se kommentaren i main(). Vi väntar på filslut från ett rör som
              kommer stängas av föräldraprocessen när den har uppdaterat
              avbildningarna. */

           close(args->pipe_fd[1]);    /* Stäng vår beskrivare för skrivänden
                                           av röret så att vi ser EOF när föräldern
                                           stänger sin beskrivare. */
           if (read(args->pipe_fd[0], &ch, 1) != 0) {
               fprintf(stderr,
                       "Fel i barnet: läsning från röret returnerade ≠ 0\n");
               exit(EXIT_FAILURE);
           }

           close(args->pipe_fd[0]);

           /* Kör ett skalkommando. */

           printf("I begrepp att göra exec %s\n", args->argv[0]);
           execvp(args->argv[0], args->argv);
           err(EXIT_FAILURE, "execvp");
       }

       #define STACK_SIZE (1024 * 1024)

       static char child_stack[STACK_SIZE];    /* Utrymme för barnets stack */

       int
       main(int argc, char *argv[])
       {
           int flags, opt, map_zero;
           pid_t child_pid;
           struct child_args args;
           char *uid_map, *gid_map;
           const int MAP_BUF_SIZE = 100;
           char map_buf[MAP_BUF_SIZE];
           char map_path[PATH_MAX];

           /* Tolka kommandoradsflaggor. Det inledande tecknet '+' i det
              sista argumentet till getopt() förhindrar permutationer av
              kommandoradsflaggor enligt GNU-stil. Det är användbart, eftersom
              ibland 'kommandot' som skall köras av detta program självt
              har kommandoradsflaggor. Vi vill inte att getopt() skall hantera
              dessa som flaggor till detta program. */

           flags = 0;
           verbose = 0;
           gid_map = NULL;
           uid_map = NULL;
           map_zero = 0;
           while ((opt = getopt(argc, argv, "+imnpuUM:G:zv")) != -1) {
               switch (opt) {
               case 'i': flags |= CLONE_NEWIPC;        break;
               case 'm': flags |= CLONE_NEWNS;         break;
               case 'n': flags |= CLONE_NEWNET;        break;
               case 'p': flags |= CLONE_NEWPID;        break;
               case 'u': flags |= CLONE_NEWUTS;        break;
               case 'v': verbose = 1;                  break;
               case 'z': map_zero = 1;                 break;
               case 'M': uid_map = optarg;             break;
               case 'G': gid_map = optarg;             break;
               case 'U': flags |= CLONE_NEWUSER;       break;
               default:  usage(argv[0]);
               }
           }

           /* -M eller -G utan -U är meningslöst */

           if (((uid_map != NULL || gid_map != NULL || map_zero) &&
                       !(flags & CLONE_NEWUSER)) ||
                   (map_zero && (uid_map != NULL || gid_map != NULL)))
               usage(argv[0]);

           args.argv = &argv[optind];

           /* Vi använder ett rör för att synkronisera förälder och barn, för
              att säkerställa att föräldern ställer in UID- och GID-avbildningarna
              före barnet anropar execve(). Detta ser till att barnet behåller
              sina förmågor under execve() i det vanliga fallet då vi vill avbilda
              barnets effektiva användar-ID på 0 i den nya användarnamnrymden.
              Utan denna synkronisering skulle barnet tappa sina förmågor om det
              utförde en execve() med användar-ID:n skilda från noll (se
              manualsidan capabilities(7) för detaljer om transformationen av en
              process förmågor under execve()). */

           if (pipe(args.pipe_fd) == -1)
               err(EXIT_FAILURE, "pipe");

           /* Skapa barnet i nya namnrymder. */

           child_pid = clone(childFunc, child_stack + STACK_SIZE,
                             flags | SIGCHLD, &args);
           if (child_pid == -1)
               err(EXIT_FAILURE, "clone");

           /* Föräldern faller igenom hit. */

           if (verbose)
               printf("%s: PID för barnet som skapades av clone() är %jd\n",
                       argv[0], (intmax_t) child_pid);

           /* Uppdatera UID- och GID-avbildningarna i barnet. */

           if (uid_map != NULL || map_zero) {
               snprintf(map_path, PATH_MAX, "/proc/%jd/uid_map",
                       (intmax_t) child_pid);
               if (map_zero) {
                   snprintf(map_buf, MAP_BUF_SIZE, "0 %jd 1",
                           (intmax_t) getuid());
                   uid_map = map_buf;
               }
               update_map(uid_map, map_path);
           }

           if (gid_map != NULL || map_zero) {
               proc_setgroups_write(child_pid, "deny");

               snprintf(map_path, PATH_MAX, "/proc/%jd/gid_map",
                       (intmax_t) child_pid);
               if (map_zero) {
                   snprintf(map_buf, MAP_BUF_SIZE, "0 %ld 1",
                           (intmax_t) getgid());
                   gid_map = map_buf;
               }
               update_map(gid_map, map_path);
           }

           /* Stäng skrivänden av röret för att signalera till barnet att vi
              har uppdaterat UID- och GID-avbildningarna. */

           close(args.pipe_fd[1]);

           if (waitpid(child_pid, NULL, 0) == -1)      /* Wait for child */
               err(EXIT_FAILURE, "waitpid");

           if (verbose)
               printf("%s: avslutar\n", argv[0]);

           exit(EXIT_SUCCESS);
       }

SE ÄVEN

       newgidmap(1), newuidmap(1), clone(2), ptrace(2), setns(2), unshare(2), proc(5), subgid(5),
       subuid(5),   capabilities(7),   cgroup_namespaces(7),    credentials(7),    namespaces(7),
       pid_namespaces(7)

       Kärnans källfil Documentation/admin-guide/namespaces/resource-control.rst.

ÖVERSÄTTNING

       Den   svenska   översättningen   av   denna   manualsida   skapades   av   Göran  Uddeborg
       <goeran@uddeborg.se>

       Denna översättning är  fri  dokumentation;  läs  GNU  General  Public  License  Version  3
       ⟨https://www.gnu.org/licenses/gpl-3.0.html⟩  eller  senare för upphovsrättsvillkor. Vi tar
       INGET ANSVAR.

       Om du hittar fel  i  översättningen  av  denna  manualsida,  skicka  ett  mail  till  ⟨Tp-
       sv@listor.tp-sv.se⟩.