Kritisk sårbarhed borer hul i de seneste otte års Linux-kerner

En kritisk sårbarhed i Linux-kernen påvirker alle kerneversioner på alle computerarkitekturer fra 2001 og frem. Sårbarheden er nu patchet.

Linux-kerner har de seneste otte år båret rundt på en kritisk sårbarhed. Først i går blev hullet lukket.

Sårbarheden er fundet af sikkerhedseksperterne Tavis Ormandy og Julien Tinnes, og den påvirker alle kerneversioner mellem 2.4 og 2.6 fra 2001 og frem til i dag på alle processorarkitekturer.

Sårbarheden skyldes en fejl i den måde, flere rutiner på kerneniveau opfører sig, hvis ikke de er blevet implementeret. Den betyder, at systemet kan kompromitteres, fordi det bliver muligt at skrive til den allerførste del af hukommelsen, som normalt er lukket område.

I Linux-kernen har hver socket tilknyttet en række operationer, proto_ops, som indeholder pointere til funktioner, der implementerer forskellige kommandoer som for eksempel accept, bind og shutdown.

Hvis en operation på en socket efterlades uimplementeret ? altså uden egentlig funktionalitet ? forventes det, at den tilknyttede funktionspointer sættes til at pege på en 'stub', en slags dummy-funktion. Hvis for eksempel accept-operationen ikke er blevet implementeret, skal den pege på funktionen socket_no_accept(), forklarer Tavis Ormandy på lwn.net.

Det er bare ikke altid sådan, klaveret spiller i Linux-kernen, har Tavis Ormandy og Julien Tinnes fundet ud af.

NULL-pointer skyld i kerne-hovedpinen
Rutinen sock_sendpage() undersøger for eksempel ikke, om funktionspointeren er gyldig, før den derefererer den. Det betyder, at funktionspointeren kan være en NULL-pointer ? altså en pointer til intet særligt sted i hukommelsen, hvilket normalt gør, at programmet crasher med et brag, når NULL-pointeren ikke håndteres i programkoden.

Kernen er dog i stand til at arbejde videre i sådan et tilfælde, men er pludselig blevet sårbar for afvikling af vilkårlig kode.

»Da det leder kernen til at afvikle kode ved NULL, er sårbarheden så triviel at udnytte, som det kan blive. En ondsindet person kan bare lægge kode ind i den første page (del af hukommelsen, red.), som så vil blive afviklet med kernerettigheder,« skriver Julien Tinnes i et blog-indlæg om sårbarheden.

Det er anden gang på en mindre end en måned, at en alvorlig NULL-pointer-sårbarhed opdages i Linux-kernen.

SSLUG: Hullet rammer usædvanligt bredt
Hos Skåne-Sjælland Linux User Group, SSLUG, vurderer man, at sårbarheden er alvorlig.

»Man kan få kernen til udføre kode fra page NULL via en NULL-pointer. Normalt vil kernen aldrig nogensinde udføre kode der, og hvis man så er i stand til at gøre det igennem en sårbarhed, har man sådan set vundet,« siger formand i SSLUG, Bryan Østergaard.

Han mener, at folkene bag de fleste Linux-distributioner lige nu arbejder på højtryk for at udsende opdateringer.

»Det sker hurtigst muligt, og jeg er sikker på, at de forskellige Linux-distributioner har travlt med at opdatere deres kerner, som formentlig vil udkomme inden for de næste få dage. Det er sådan tidslinjen typisk ser ud,« siger Bryan Østergaard.

Ifølge Bryan Østergaard er det svært at gardere sig fuldstændigt mod den slags alvorlige fejl.

»Der er flere millioner linjer Linux-kode, og mange af dem spiller ind og påvirker hinanden. Det kan nogle gange være svært at overskue de samlede konsekvenser af, hvad der egentlig kan ske,« siger han.

»Problemet kan være, at det nogle gange kan se ud som om, at der ikke kan opstå en NULL-pointer. Udviklerne gør selvfølgelig alt, hvad de kan for at undgå den slags fejl, og så er der heldigvis nogle sikkerhedsfolk, som har det specielle 'mindset', der skal til for at fange den slags huller,« uddyber Bryan Østergaard.

Han påpeger, at kernen har i flere år har været en tur igennem en statisk analyse, hvor koden analyseres på alle leder og kanter.

»Men selvom de kan analysere millioner af veje gennem koden, så er det ikke altid, at man fanger fejlene. Det er en del af software, at det aldrig kan blive hundrede procent perfekt,« siger Bryan Østergaard.

Men er det ikke usædvanligt, at et sikkerhedshul rækker så mange år tilbage?

»Jo, absolut. Normalt bliver den slags fanget væsentlig hurtigere, og det er også usædvanligt, at sårbarheden rammer så mange kerneversioner. Typisk rækker sikkerhedsbugs kun et halvt års tid tilbage, og selvom man før har set nogle række flere år tilbage, hører det til sjældenhederne,« siger Bryan Østergaard.

Tips og korrekturforslag til denne historie sendes til tip@version2.dk
Kommentarer (22)
sortSortér kommentarer
  • Ældste først
  • Nyeste først
  • Bedste først
#2 Peter Mogensen

Det afgør det som den uinitialiserede funktionspointer peger på.

Nu er jeg ikke kerneudvikler, men jeg vil gætte på at det som menes er at alle kerneoperationer egentlig er en pointer i en "jump-table" ligende ting. Hvis man ikke implementerer alle funktioner skal man jo huske at give de resterende pointere meningsfulde (og sikre) værdier.

  • 0
  • 0
#4 Ole Wolf

Jeg skal gerne indrømme, at jeg ikke har nogen ekspertise i det her, men når der bliver sagt:

"En ondsindet person kan bare lægge kode ind i den første page (del af hukommelsen, red.), som så vil blive afviklet med kernerettigheder,"

så forestiller jeg mig dog, at man muligvis ikke "bare" uden videre kan lægge kode ind i de hukommelsesområder, man selv har lyst til. Eller er der en nem måde at gøre det på?

  • 0
  • 0
#6 Rene Madsen

Det er dit OS der bestemmer hvor et program må skrive til og læse fra. Selve maskinen gør bare hvad den får besked på. Så er der en fejl i OS kernen så du kan komme uden om denne begrænsning (som her) så kan programmet skrive/læse uden for det oprindeligt tiltænkte område.

Men det kræver jo i første omgang at du i et eller andet omfang har mulighed for at starte et program op på maskinen, før du kan udnytte den her fejl, sådan som jeg forstår fejlen. Altså har en maskine der er 100% styret af en administrator ikke et kritisk problem, med mindre eksiserende software har mulighed for at ramme det her hul.

Efter som at der ikke er massere af Linux maskiner der går ned på stribe rundt omkring i verdenen, tolker jeg det som at der ikke er ret meget software der rammer det her hul.

  • 0
  • 0
#7 Carsten Hess

"Pivilege escalation" fejl er måske ikke så grimme alene, men kombineret med en sårbarhed i f.eks. PHP der tillader afvikling af vilkårlig kode (og dem er der jo nogle af fra tid til anden), giver det pludselig mulighed for at afvikle vilkårlig kode som root udefra, uanset at din apache kører som ikke-priviligeret bruger.

  • 0
  • 0
#8 Alexander Færøy

"Pivilege escalation" fejl er måske ikke så grimme alene, men kombineret med en sårbarhed i f.eks. PHP der tillader afvikling af vilkårlig kode (og dem er der jo nogle af fra tid til anden), giver det pludselig mulighed for at afvikle vilkårlig kode som root udefra, uanset at din apache kører som ikke-priviligeret bruger.

Der vil et system som SELinux dog kunne redde din røv inden angriberen rent faktisk får lov til at eksekvere kode, der kan gøre skade (og slå SELinux fra ;)

  • 0
  • 0
#9 Lars Tørnes Hansen

@Peter Mogensen

"Nu er jeg ikke kerneudvikler, men jeg vil gætte på at det som menes er at alle kerneoperationer egentlig er en pointer i en "jump-table" ligende ting. Hvis man ikke implementerer alle funktioner skal man jo huske at give de resterende pointere meningsfulde (og sikre) værdier"

Næsten korrekt! Der er en jumptable som oprettes af driveren, pointeren til jumptabellen bruges af kernen til at 'snakke med' driveren.

De fleste uintialiserede funktioner (NULL pointere i jumptabellen) skal resultere i at kernen selv skal kalde en dummy funktion.

  • 0
  • 0
#10 Keld Simonsen

Altså, jeg forstår ikke hvor alvorligt dette hul er. Er det ikke meget svært at trænge igennem det?

Jeg ser kun på situationen hvor folk vil ind via nettet.

For det første skal de aktivere en uinitialiseret handler. jeg vil tro at de fleste handlere, som kunne bruges i systemer der er adgang til udefra, er initialiserede. Men hvad véd jeg. Almindelige servere såsom web, ftp, databaser, ssh tror jeg ikke benytter ting der bruger nogen af disse handlere i kernen, eller hur?

For det andet skal indtrængeren i forvejen have anbragt noget skadelig kode på adresse 0000 i kernens adresserum. Det gør man altså ikke lige. Heller ikke hvis man kommer igennem et eller andet hul i noget PHP-kode styret af Apache. Apache har ikke mulighed for at skrive i kernens adresserum, da den kører upriviligeret.

Og er det ikke let at patche? Man kunne vel bare tjekke for om den procedure, men kalder, er NIL. Det burde man egentlig gøre for alle funktionskald.

Så er dette ikke et obskurt sikkerhedshul, som i praksis er umuligt at lave exploit på, og bare bliver hypet i medierne, så man har noget mudder at kaste efter Linux?

  • 0
  • 0
#11 Alexander Færøy

Jeg ser kun på situationen hvor folk vil ind via nettet.

Det er fjollede at være så snæversynet omkring noget så kritisk.

Det virker overhovedet ikke som at du har læst (eller forstået) det som det handler om i den her artikel; det er et lokalt root-exploit.

Når et program laver et systemkald, hvilket alle ikke-trivielle Unix-programmer gør, bevæger programmet sig fra userland og ned i kernelspace, ergo er dit program pludselig i kernelspace; her er der selvfølgelig en masse checks som sikrer sig, at du ikke laver ting som du ikke må, men i det her tilfælde kan du altså få lov til at eksekvere kode via kernen, og får du så smidt noget kode ned i den adresse som NULL er, kan du altså få kernen til at eksekvere koden, hvilket du så f.eks. kan udnytte til at give dig en root-shell. Pludselig har din "upriviligeret" Apache-proces, som en person har angrebet og fået kontrol over, givet ham en root-shell (eller bundet en root-shell på en TCP-port f.eks.).

Så er dette ikke et obskurt sikkerhedshul, som i praksis er umuligt at lave exploit på, og bare bliver hypet i medierne, så man har noget mudder at kaste efter Linux?

Nej, det er det ikke. Tavis har bidraget med mere til Linux-verdenen end de fleste har, og at han bliver ved med at finde "obskure" (hvilket det er, da ingen har fundet det før nu) sikkerhedsfejl er kun til vores fordel.

  • 0
  • 0
#12 Deleted User

Måden det er udnyttet er ikke helt så simpel.

For det første er det ikke muligt at skrive til den første del af adressespace normalt. For at kunne udnytte det kræver det at programmet kører som root (evt. setuid); og for en gangs skyld er du ved en fejl faktisk dårligere stillet med SELinux end uden...

Jeg vil anbefale at kigge på http://lwn.net/Articles/341620/ som forklarer det rigtig godt!

  • 0
  • 0
#14 Keld Simonsen

Jeg så kun på angreb udefra, fordi at hvis indtrængeren allerede var trængt ind, så var der nok andre og mere alvorlige problemer. Og jeg havde ikke set at problemet var kategoriseret som kun et lokalt root-exploit, men min næse sagde mig at det var.

Det er altså kun hvis man i forvejen er trængt ind og har shell-adgang, og kan lægge sine egne progrmmer ind, at det kan være farligt. Det kræver også at man kan lægge noget kode ind i kernens nederste lagerdel fra adresse 0000 og frem. Dette kan main ikke på de fleste nyere kerner, som bruger mmap_min_addr, og dermed forhindrer at adresserummet kan mappes til adresse 0000. I nogen af de nyeste kerner fra kerne 2.6.30 og til hullet blev stoppet forleden, kunne man omgå mmap_min_addr beskyttelsen med SELinux sikkerhedssystemet, fordi nogen binære programmer har brug for at udføre kode i adresse 0000, og det var standardsetup i nogen distributioner.

Summasummarum: Dette sikkerhedshul er ikke åbent udefra. det er ikke åbent på de fleste nyere distributioner der bruger mmap_min_addr. En undtagelse kan være kerne 2.6.30 med SELinux.

Konklusion: der er ikke grund til panik, og for de allerfleste brugere af linux er der ikke nogen sikkerhedsrisiko.

Kører du kerne 2.6.30 og bruger SELinux, med dårlige sikkerhedsindstillinger, og har brugere på dine sytemer som du ikke stoler på, så opgradér med det samme (eller ændr på SELinux indstillinger.

  • 0
  • 0
#15 Keld Simonsen

Jeg har stadig ikke forstået hvordan et upriviligeret program kan få lov at skrive i kernens adresserum, herunder fra adresse 0000 og frem.

Hvis alle bare kunne skrive i vilkårlige adresser i kernens adresserum, ja så kunne enhver bruger da hurtigt ødelægge systemet.

  • 0
  • 0
#16 Bryan Østergaard

Det er lidt noget sludder at tale om kernens adresserum - du har et samlet adresserum som kernen og din process lever i. På 32-bit maskiner (uden PAE / page address extensions slået til) er de nederste 3GB typisk forbeholdt userspace og den øverste 1GB forbeholdt kernen.

Hele dette adresserum er dog virtuelt og kernen mapper så fysisk hukommelse ind som det måtte være nødøvendigt.

Det specifikke exploit mapper så page 0 via f.eks. mmap og skriver den kode til map'ingen som man gerne vil have kørt med kernel privilegier og udnytter til sidst det hul til som Tavis og Julien har fundet til at få kernen til at kalde koden på adresse 0.

Selve exploitet er som sådan ret trivielt men det er godt gået at finde et hul som har været overset så længe. Især når man tager i betragtning at netværksdelen af kernen altid har været meget aktivt vedligeholdt.

  • 0
  • 0
#17 Keld Simonsen

Adresserummet i userland og kernelspace kan ikke være det samme. Ellers vil userland have adgang til alle informationer, som kernen har, og det er en væsentlig sikkerhedsbrist.

Og userland kan da ikke vilkårligt mappe memory om, så en brugerproces kan skrive i RAM, som kernen så efterfølgende bruger. Så ville en brugerproces jo kunne udskifte vilkårlige dele af kernens kode eller data.

Som jeg har forstået det bevirker et systemkald at man skifter til kernel mode og samtidigt skifter adresserum, eller memory mapping, (derfor taler jeg om kernens adresserum). En bruger har ikke adgang til at bestemme over denne adresserumsopsætning, det er bestemt af kernen.

Eller hur?

  • 0
  • 0
#18 Bryan Østergaard

Forkert, forkert og atter forkert. Der er en simpel form for access control list der styrer adgangen til forskellige dele af adresserummet.

Kernen og userspace applikationer kører i forskellige "ringe" og det bruges til at begrænse adgangen sammen med bits der siger om man må læse, skrive og eksekvere kode fra den enkelte hukommelsesside - hvor en side typisk er 4KB på x86 og amd64 arkitekturerne.

Det er i øvrigt heller ikke muligt at kalde kode i et andet addresserum direkte da man ikke kan pege på noget uden for ens eget addresserum. Det vil derfor som absolut minimum være nødvendigt med en form for trampolin til at springe fra applikationens addresserum til kernens og så har du reelt samme problem igen.

Desuden er det temmeligt dyrt at mappe adresserum om så det gør man generelt ikke.

  • 0
  • 0
#19 Lars Jeppesen

Man kan lidt simpelificeret forklare det således. (for et 32bit system med 1GB kernelspace) Hver process har et virtuelt addresserum på 4GB. De øverste 1GB benytter kernen til data og kode. Når usermode koden eksekveres (fra de nederste 3GB) har kernen konfiguret den virtuelle memory controller således at enhver tilgang til de øverste 1GB udløser en exception. (Man kan dog stadig sige at de ligger i addresserummet, man har bare ikke adgang dertil.) De nederste 3GB memory kan derfor bruges som processen har lyst til. Hvis den har lyst til at bruge addresse 0, kan den det. Dette betyder normalt ikke noget da alt kerne data og kode er placret i de øverste 1GB. Problemet er bare at denne fejl gør at kernen hopper til addresse nul uden at skifte til usermode. Og da man kan skrive hvad man vil på addresse 0, kan man skrive noget kode, som så vil blive udført som om det var kerne kode.

  • 0
  • 0
#21 Bryan Østergaard

Det er noget sludder at snakke om at addresserummet 0000 ligger i userland. Man har (på moderne operativsystemer som f.eks. Linux) et (virtuelt) addresserum der dækker adskillige gigabytes og inkluderer både userland og kernelspace.

DOS var helt anderledes da man kun havde et enkelt addresserum (det fysiske) og der ikke var nogen beskyttelse af nogen art. Alle programmer kunne derfor frit skrive og læse til en hvilken som helst del af hukommelsen.

  • 0
  • 0
#22 Keld Simonsen

Bryan, jeg tror vi forstår hinanden nu. Der er et virtuelt adresserum i Linux, der i x386-arkitekturen er lagt ud på den måde at de første 3 GiB er userland, og den sidste 1 Gib er kernens.

Alle andre Unixer, og for den sags skyld også Windows og DOS har også et layout af adresserum. Nogen arkitekturer og systemer lægger systemets plads fra adresse 0 og fremefter, men sådan er det ikke i x386 Linux.

  • 0
  • 0
Log ind eller Opret konto for at kommentere