Secomp

seccomp (förkortat från engelska  secure computing mode ) är en av säkerhetsmekanismerna i Linux-kärnan , som ger möjlighet att begränsa uppsättningen av tillgängliga systemanrop för applikationer, och även använda BPF-mekanismen ( Berkeley Packet Filter ) för att utföra komplex filtrering samtal och deras argument. Dök upp först i kärnversion 2.6.12 2005 [1] [2] .

För att arbeta med opålitliga eller overifierade, och därför potentiellt farliga program, är det tillrådligt att använda speciellt dedikerade miljöer från vilka det är omöjligt att skada systemets prestanda som helhet. I sådana miljöer (sandlådor, behållare) är många systemfunktioner begränsade för att köra program, såsom åtkomst till nätverket, I/O-enheter och interaktion med operativsystemet. Seccomp-mekanismen bestämmer mängden tillåtna systemanrop för processen och blockerar de som inte tidigare deklarerats. Det används för närvarande i ett antal webbläsare , Linux-liknande operativsystem och vissa virtualiseringssystem .

Historik

Seccomp-mekanismen utvecklades av Andrea Arcangeli ( italienska  Andrea Arcangeli ) som en del av det kommersiella CPUShare-projektet, vars huvudidé var att fastställa kapaciteten och utveckla lösningar för att tillhandahålla datorresurser till datorer, särskilt med Linux OS, för exekvera tredjepartskod. Dök upp först i Linux-kärnan i mars 2005 (version 2.6.12). I den första versionen, för att aktivera seccomp, var processen tvungen att skriva en "1" till filen /proc/PID/seccomp. Därefter var endast fyra systemsamtal tillgängliga för gästkoden: read(), write(), exit()och sigreturn()[3] . Under 2007 lade version 2.6.23 till möjligheten att aktivera seccomp via ett systemanrop prctl()med PR_SET_SECCOMP-operationen, och /proc-gränssnittet togs bort [4] .

Trots att CPUShare-projektet, för vilket seccomp utvecklades, inte utvecklades och stängdes, fanns det kvar i Linux-kärnan [3] . I februari 2009 upptäcktes en sårbarhet i seccomp-koden. Det berodde på att i 32-bitars och 64-bitarsversioner av Linux motsvarade olika systemanrop samma nummer. Till exempel read()motsvarade ett tillåtet anrop från 64-bitarsversionen ett förbjudet anrop restart_syscall()från 32-bitarsversionen. Efter det uppstod frågan om att ta bort seccomp från Linux, och Linus Torvalds föreslog att seccomp inte användes av någon [5] .

Eftersom seccomp var tillräckligt enkelt att använda, hade utvecklarna av Google Chrome idén att implementera ett verktyg för att köra plugins från tredje part baserat på det . Men för att uppnå detta mål var det inte tillräckligt att bara blockera alla utom de fyra tillåtna systemanropen. Som ett resultat, 2012, integrerades BPF-mekanismen (Berkeley Packet Filter) med seccomp (i version 3.5 lades ett andra driftläge till - SECCOMP_MODE_FILTER), vilket avsevärt utökade mekanismens kapacitet - efter innovationen, gästen processen kan mer flexibelt välja uppsättningen av tillåtna och förbjudna systemanrop genom att bifoga lämpligt BPF-program. 2012 dök även biblioteket libsecomp upp, som ger ett enkelt och bekvämt API för att filtrera systemanrop [4] .

För att förenkla användningen av seccomp lade version 3.8 2013 till "Seccomp"-fältet till /proc/PID/status, vilket låter dig ta reda på statusen för seccomp (efter att inkluderingen togs bort från /proc var det omöjligt att ta reda på om den redan aktiverade seccomp kördes utan att avsluta processen). Under 2014 lade version 3.17 till ett speciellt systemanrop - seccomp(), som delvis upprepar funktionen prctl()[4] .

I november 2017, med lanseringen av glibc- biblioteksversionen 2.26, dök ett nytt problem upp: eftersom i C -program görs systemanrop inte direkt, utan genom omslag av standardbiblioteket, vars namn kanske inte matchar namnen på systemanrop, förbudet mot ett samtal kan oväntat påverka programmet. Till exempel implementeras en funktion från glibc-standardbiblioteket version 2.26 via ett systemanrop , vilket inte är detsamma som ett anrop och som felaktigt kan blockeras av filterförfattaren [6] . open()openat()open()

Beskrivning

Du kan använda systemanropet seccomp()eller för att aktivera seccomp i ditt program prctl(). Det finns för närvarande två driftslägen för seccomp: SECCOMP_MODE_STRICT och SECCOMP_MODE_FILTER. Du kan ta reda på om seccomp är aktiverat och i vilket läge från "Seccomp"-fältet i filen /proc/[pid]/status. Fältet tar värdena 0, 1 eller 2: 0 — seccomp är inte aktiverat för processen, 1 — seccomp i SECCOMP_MODE_STRICT-läge, 2 — i SECCOMP_MODE_FILTER-läge [4] . Du kan inte aktivera seccomp för andra processer [7] .

SECCOMP_MODE_STRICT-läge

Var det enda driftsättet före Linux 3.5. För att använda den måste kärnan konfigureras med tangenten CONFIG_SECCOMP=y [2] .

För att gå in i detta läge måste du ringa ett samtal prctl(PR_SET_SECCOMP, SECCOMP_MODE_STRICT)eller på motsvarande sätt seccomp(SECCOMP_SET_MODE_STRICT, 0, NULL). Nu kan en process bara använda fyra systemanrop: read(), write(), _exit()och sigreturn()[3] . Andra systemanrop kommer att resultera i att processen avslutas med en SIGKILL-signal. Eftersom systemanropet open()är inaktiverat om seccomp ska kontrolleras måste statusfilen från procfs öppnas med läsbehörigheter innan seccomp aktiveras i processen [4] .

SECCOMP_MODE_FILTER-läge

Ett driftläge introducerat i Linux-kärnan version 3.5 [8] . Tillgänglig om CONFIG_SECCOMP_FILTER=y-flaggan sattes när kärnan byggdes.

Innan du går in i detta läge måste ett anrop göras prctl(PR_SET_NO_NEW_PRIVS, 1)och därför måste no_new_privs-biten ställas in för processen. Anledningen till detta krav är att annars skulle en oprivilegierad process kunna köra ett privilegierat program med execve(). Om detta inte görs kommer övergången till SECCOMP_MODE_FILTER-läget att misslyckas [4] .

Efter att ha ställt in no_new_privs-biten, för att koppla filtret till processen, måste du anropa prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, args)eller seccomp(SECCOMP_SET_MODE_FILTER, 0, args), där args är en pekare till strukturen sock_fprog, som består av en array av BPF-instruktioner och dess längd. Filtret körs varje gång processen gör ett systemanrop. När det startas får filtret som indata en struktur med data om systemets anropsnummer, arkitektur, aktuellt tillstånd för programräknaren och anropsargument [7] [8] . Filtret måste returnera ett 32-bitars värde, där de övre 16 bitarna innehåller koden för åtgärden som ska utföras, och de lägre 16 bitarna innehåller data. Om filteralgoritmen inte ger ett returvärde av misstag, kommer den inte att klara statisk analys och ett sådant filter kommer inte att bifogas [9] .

Om flera filter är kopplade till en process kommer de att länkas var för sig och köras i omvänd ordning som de lades till, även om ett av filtren skulle döda processen [7] . I ett sådant fall kommer returvärdet för systemanropet att bestämmas av det första (i den ordning som filtren körs) returvärdet med högst prioritet, enligt tabellen (i fallande prioritetsordning) [10] :

Handling Resultat
SECCOMP_RET_KILL Systemanrop misslyckas, processen kommer att dödas med signalen SIGSYS [4]
SECCOMP_RET_TRAP Systemanropet misslyckas, processen tar emot SIGSYS-signalen, signalhanteraren har tillgång till information om systemanropet som gav detta resultat
SECCOMP_RET_ERRNO Systemanropet exekveras inte, errnofiltrets returvärde finns i variabeln
SECCOMP_RET_TRACE Om ett ptrace()spårämne specificeras för en process med hjälp kommer det att meddelas om samtalet. Om det inte anges, exekveras inte systemanropet.
SECCOMP_RET_ALLOW Systemsamtal pågår

Användningsexempel

Aktiverar SECCOMP_MODE_STRICT [4]

# include <stdio.h> # include <unistd.h> # include <linux/secomp.h> # include <sys/prctl.h> # include <fcntl.h> int main () { int fd ; prctl ( PR_SET_SECCOMP , SECCOMP_MODE_STRICT ); fprintf ( stderr , "försök öppna \n " ); fd = öppen ( "test_fil" , O_CREAT ); fprintf ( stderr , "fd = %d" , fd ); returnera 0 ; }

Resultat av arbetet:

$ gcc test_seccomp.c -o test_seccomp $ ./test_secomp försök öppna Dödad

I exemplet ovan, efter samtalet, prctl()körs processen exakt till det ögonblick då den försöker ringa ett samtal till open().

Exempel på användning i programvara

Anteckningar

  1. 1 2 3 Imamjafar Borate, Chavan RK, 2016 .
  2. 12 Kroah -Hartman, 2007 .
  3. 1 2 3 Kurt Dietrich, Johannes Winter, 2011 .
  4. 1 2 3 4 5 6 7 8 Jake Edge, Michael Kerrisk, 2015 .
  5. Jonathan Corbet. Secomp och sandboxing  // LWN.net. - 2009. - 13 maj. Arkiverad från originalet den 12 november 2017.
  6. Jonathan Corbet. Den inneboende bräckligheten av secomp()  // LWN.net. - 2017. - 1 november. Arkiverad från originalet den 9 december 2017.
  7. 1 2 3 Lingguang Lei, Jianhua Sun, Kun Sun, Chris Shenefiel, Rui Ma, Yuewu Wang, Qi Li, 2017 .
  8. 1 2 Taesoo Kim, Nickolai Zeldovich, 2013 .
  9. Steven McCanne, Van Jacobson, 1993 .
  10. SECure COMPuting med filter . Linux-kärnarkivet . Linux kärnorganisation. Hämtad 3 mars 2018. Arkiverad från originalet 13 oktober 2017.
  11. Anto.Y, 2012 .
  12. Adrian Mouat, 2015 .
  13. Senthil Kumaran S., 2017 .

Litteratur

  • Steven McCanne, Van Jacobson. BSD-paketfiltret: en ny arkitektur för paketfångning på användarnivå  // 1993 Winter USENIX. - San Diego, CA, 1993. - 2 januari.
  • Greg Kroah Hartman. Linux-kärnan i ett nötskal. - 1005 Gravenstein Highway North, Sebastopol, CA 95472: O'Reilly Media, 2007. - 208 sid. — ISBN 978-0596100797 .
  • Michael Kerris. Linux-programmeringsgränssnittet. - San Francisco: No Starch Press, 2010. - 1556 sid. - ISBN 978-1-59327-220-3 .
  • Jake Edge, Michael Kerrisk. En seccomp översikt  // LWN.net : Linux Plumbers Conference. - Seattle, Washington, USA, 2015. - 1 september.
  • Taesoo Kim, Nickolai Zeldovich. Praktisk och effektiv sandboxning för icke-rootanvändare  // 2013 USENIX årliga tekniska konferens. — 2013.
  • Ma Bo, Mu Dejun, Fan Wei, Hu Wei. Förbättrar Secomp-sandlådan baserad på PBE-teori   // IEEE . - 2013. - 1 juli. - doi : 10.1109/WAINA.2013.81 .
  • Imamjafar Borate, Chavan RK Sandboxning i Linux: Från smartphone till moln  //  International Journal of Computer Applications. - 2016. - August ( vol. 148 , nr 8 ).
  • Senthil Kumaran S. Praktisk LXC och LXD: Linux-behållare för virtualisering och orkestrering. - Apress, 2017. - S. 147. - 159 sid. - ISBN 978-1-4842-3024-4 .
  • Adrian Mouat. Använda Docker: Utveckla och distribuera programvara med behållare. - 1005 Gravenstein Highway North, Sebastopol, CA 95472: O'Reilly Media, 2015. - s. 320. - 354 s.
  • Kurt Dietrich, Johannes Winter. Mot ett pålitligt, lättviktigt molnberäkningsramverk för inbyggda system  // Trust and Trustworthy Computing: 4:e internationella konferensen. - Pittsburgh, PA, USA: Springer, 2011. - Juni.
  • Anto.Y. Chrome OS och Secret of Google. - Lambert Academic Publishing, 2012. - S. 41. - 228 sid. — ISBN 978-3-659-17127-7 .
  • Lingguang Lei, Jianhua Sun, Kun Sun, Chris Shenefiel, Rui Ma, Yuewu Wang, Qi Li. SPEAKER: Split-Phase Execution of Application Containers  // Detection of Intrusions and Malware, and Vulnerability Assessment: 14th International Conference, DIMVA 2017. - Bonn, Tyskland: Springer, 2017. - 1 juli.

Länkar