Minnessäkerhet
Minnessäkerhet är tillståndet att vara skyddad från olika programvarubuggar och säkerhetssårbarheter när man hanterar minnesåtkomst , såsom buffertspill och dinglande pekare . Till exempel Java vara minnessäkert eftersom dess runtime error-detektering kontrollerar arraygränser och pekarreferenser. Däremot C och C++ godtycklig pekarearitmetik med pekare implementerade som direkta minnesadresser utan bestämmelser för kontroll av gränser , och är därför potentiellt minnesosäkra .
Historia
Minnesfel övervägdes först i samband med resurshantering_(dator) och tidsdelningssystem , i ett försök att undvika problem som gaffelbomber . Utvecklingen var mestadels teoretisk fram till Morris-masken , som utnyttjade ett buffertspill i fingerd . Området för datorsäkerhet utvecklades snabbt därefter och eskalerade med mängder av nya attacker såsom återvända till libc-attacken och försvarstekniker såsom den icke-körbara stack och randomisering av adressutrymmeslayout . Randomisering förhindrar de flesta buffertspillattacker och kräver att angriparen använder heap-spraying eller andra applikationsberoende metoder för att erhålla adresser, även om det har gått långsamt. Utplaceringar av tekniken är dock vanligtvis begränsade till slumpmässiga bibliotek och platsen för stacken.
Påverkan
Under 2019 rapporterade en säkerhetsingenjör från Microsoft att 70 procent av alla säkerhetsbrister orsakades av minnessäkerhetsproblem. År 2020 rapporterade ett team på Google på samma sätt att 70 procent av alla "allvarliga säkerhetsbuggar" i Google Chromium orsakades av minnessäkerhetsproblem. Många andra högprofilerade sårbarheter och utnyttjande av kritisk programvara har i slutändan härrört från bristande minnessäkerhet, inklusive Heartbleed och en långvarig privilegieskaleringsbugg i sudo . Den genomgripande och svårighetsgraden av sårbarheter och utnyttjande som härrör från minnessäkerhetsproblem har fått flera säkerhetsforskare att beskriva att identifiera minnessäkerhetsproblem som " att skjuta fisk i en tunna" .
Närmar sig
De flesta moderna högnivåprogrammeringsspråk är minnessäkra som standard, dock inte helt eftersom de bara kontrollerar sin egen kod och inte systemet de interagerar med. Automatisk minneshantering i form av skräpinsamling är den vanligaste tekniken för att förhindra några av minnessäkerhetsproblemen, eftersom den förhindrar vanliga minnessäkerhetsfel som use-after-free för all data som allokeras inom språkkörningstiden. I kombination med automatisk kontroll av gränser på alla arrayåtkomster och inget stöd för rå pekararitmetik , ger skräpinsamlade språk starka minnessäkerhetsgarantier (även om garantierna kan vara svagare för operationer på låg nivå som uttryckligen markerats som osäkra, till exempel användning av ett främmande funktionsgränssnitt ). Men prestandaoverheaden för sophämtning gör dessa språk olämpliga för vissa prestandakritiska tillämpningar.
För språk som använder manuell minneshantering garanteras vanligtvis inte minnessäkerhet av körtiden, men SLIMalloc, en minnesallokator publicerad 2020, har visat att det skulle kunna göras. Istället måste minnessäkerhetsegenskaper antingen garanteras av kompilatorn via statisk programanalys och automatiserad teorembevisande eller noggrant hanteras av programmeraren vid körning. Till exempel programmeringsspråket Rust en lånekontroll för att säkerställa minnessäkerhet, medan C och C++ inte ger några minnessäkerhetsgarantier. Den stora mängden programvara som skrivits i C och C++ har motiverat utvecklingen av externa statiska analysverktyg som Coverity , som erbjuder statisk minnesanalys för C.
DieHard, dess omdesignade DieHarder och Allinea Distributed Debugging Tool är speciella heap-allokatorer som allokerar objekt på sin egen slumpmässiga virtuella minnessida, vilket gör att ogiltiga läsningar och skrivningar kan stoppas och felsökas med exakt den instruktion som orsakar dem. Skyddet förlitar sig på hårdvaruminnesskydd och därför är overhead vanligtvis inte betydande, även om det kan växa avsevärt om programmet använder allokering mycket. Randomisering ger endast probabilistiskt skydd mot minnesfel, men kan ofta enkelt implementeras i befintlig programvara genom att länka om binären.
Valgrinds memcheck-verktyg använder en instruktionsuppsättningsimulator och kör det kompilerade programmet i en minneskontrollerande virtuell maskin, vilket ger garanterad upptäckt av en delmängd av runtime-minnesfel. Den saktar dock vanligtvis ned programmet med en faktor 40 och måste dessutom uttryckligen informeras om anpassade minnesallokatorer.
Med tillgång till källkoden finns det bibliotek som samlar in och spårar legitima värden för pekare ("metadata") och kontrollerar varje pekaråtkomst mot metadata för giltighet, såsom Boehm garbage collector . Generellt sett kan minnessäkerhet garanteras säkert genom att spåra sophämtning och infogning av körtidskontroller på varje minnesåtkomst; detta tillvägagångssätt har omkostnader, men mindre än Valgrinds. Alla skräpinsamlade språk använder detta tillvägagångssätt. För C och C++ finns det många verktyg som utför en kompileringstransformation av koden för att göra minnessäkerhetskontroller vid körning, som CheckPointer och AddressSanitizer som lägger på en genomsnittlig nedgångsfaktor på 2.
SLIMalloc, som introducerades av en ResearchGate-publikation 2020 med en större uppdatering 2023, ger realtidsskydd mot allokeringssårbarheter i applikationer, bibliotek, körtider och systemet genom att detektera, blockera, lokalisera och dokumentera (via reverse-engineering i realtid) minnes- och systemfel, samtidigt som det inte orsakar några CPU- eller minneskostnader jämfört med standard Linux -allokatorn, Mimalloc från Microsoft Research, JEmalloc från Facebook och TCmalloc från Google. SLIMalloc har certifierats på SUSE Linux och lagts till i SUSE Partner Solutions och IT Magazine "Programmez!" publicerade en artikel om SLIMalloc.
Typer av minnesfel
Många olika typer av minnesfel kan uppstå:
-
Åtkomstfel : ogiltig läsning/skrivning av en pekare
- Buffertspill – out-of-bound skrivningar kan korrumpera innehållet i angränsande objekt, eller intern data (som bokföringsinformation för högen ) eller returadresser .
- Buffertöverläsning – out-of-bound-läsningar kan avslöja känsliga data eller hjälpa angripare att kringgå randomisering av adressutrymmeslayout .
- Tävlingsvillkor – samtidiga läsningar/skrivningar till delat minne
- Ogiltigt sidfel – åtkomst till en pekare utanför det virtuella minnesutrymmet. En nollpekardereferens kommer ofta att orsaka ett undantag eller programavslutning i de flesta miljöer, men kan orsaka korruption i operativsystemets kärnor eller system utan minnesskydd , eller när användning av nollpekaren innebär en stor eller negativ offset.
- Använd efter gratis – hänvisning till en dinglande pekare som lagrar adressen till ett objekt som har raderats.
-
Oinitierade variabler – en variabel som inte har tilldelats något värde används. Den kan innehålla ett oönskat eller, på vissa språk, ett korrupt värde.
- Null-pekare- dereferens – därhänvisning till en ogiltig pekare eller en pekare till minne som inte har tilldelats
- Vilda pekare uppstår när en pekare används före initialisering till något känt tillstånd. De visar samma oberäkneliga beteende som dinglande pekare, även om de är mindre benägna att förbli oupptäckta.
-
Minnesläcka – när minnesanvändning inte spåras eller spåras felaktigt
- Stackutmattning – uppstår när ett program får slut på stackutrymme, vanligtvis på grund av för djup rekursion . En skyddssida stoppar vanligtvis programmet, vilket förhindrar minneskorruption, men funktioner med stora stackramar kan kringgå sidan.
- Hög utmattning – programmet försöker allokera mer minne än den tillgängliga mängden. På vissa språk måste detta villkor kontrolleras manuellt efter varje tilldelning.
- Dubbel gratis – upprepade samtal till gratis kan i förtid frigöra ett nytt objekt på samma adress. Om den exakta adressen inte har återanvänts kan annan korruption uppstå, särskilt hos allokatorer som använder gratislistor .
- Ogiltig gratis – att skicka en ogiltig adress till gratis kan förstöra högen .
- Felaktig ledig – när flera allokatorer används, försöker frigöra minne med en avallokeringsfunktion från en annan allokator
- Oönskad aliasing – när samma minnesplats allokeras och modifieras två gånger för orelaterade ändamål.