En allvarlig bugg i Oracle

2012-01-23

I över två månader har arbete pågått med att kartlägga en bugg i Oracles databasmotor. Denna bugg gäller dessvärre alla på marknaden förekommande versioner, och beskrivs som mycket allvarlig. Innan det är läge för utbredd panik vill jag påpeka att det är en låg risk att buggen triggas på egen hand, något högre risk om det finns en aktiv handling bakom, och att det kräver en hyfsat komplex miljö för att buggen ska kunna uppstå.

Problemet ligger i hanteringen av SCN, System Change Number. SCN kan enklast beskrivas som klockan i databasmiljön, ett obevekligt styrande värde som i varje läge bestämmer vilka transaktioner som körts i vilken ordning. Det används för bland annat mekanismer som läskonsistens, återställning och synkronisering mellan databaser, för att nämna några.

SCN kan aldrig räknas nedåt, utan kan bara räknas upp. Det enda sättet att nolla SCN är att exportera databasen, ta bort den, skapa den på nytt och läsa in datat – en tidsödande operation även på relativt små databaser.

Variabeln som håller reda på SCN är en rätt stor variabel; 48 bitar (281,474,976,710,656). Sannolikheten att SCN skulle ta slut vid ett givet tillfälle framstår som högst osannolik, speciellt som det inte riktigt är så enkelt. Det finns nämligen en ”mjuk” gräns också, som hänger ihop med en mekanism som databasen använder internt för att upptäcka om SCN skulle komma att bli ”orimligt” högt. Databasen räknar helt enkelt antalet sekunder sedan 00:00:00 den 1/1-98 och multiplicerar med 16384.  Sålänge det nuvarande SCN-värdet är under detta värde är allt som det ska, då ett SCN-värde högre än hos en fiktiv databas som körts konstant sedan -98 och har 16384 transaktioner per sekund är just – orimligt.

Här nånstans börjar de flesta människor klia sig i huvudet – vi har redan konstaterat att det är så orimliga siffror att det är lika osannolikt att få problem här som med Tage Danielssons sannolikhetsmonolog kring Three Mile Island.

Vad skulle kunna få SCN att höjas fortare än vad som är rimligt? Uppenbarligen krävs det ju något som skulle få SCN att hoppa mycket mer än med ett för varje transaktion? Tänk på vad jag tidigare skrev om synkronisering. I en komplex miljö med flera databaser som sinsemellan är kopplade via databaslänkar måste SCN synkroniseras mellan dem för att möjliggöra konsistenta transaktioner. I enlighet med vad vi redan konstaterat måste SCN alltid rulla framåt, således kommer alla ingående databaser få sitt SCN justerat uppåt, till det högsta värdet. Det är möjligt – men enormt orimligt – att en miljö med enormt många hopkopplade databaser tillsammans kan prestera fler än 16384 committade transaktioner per sekund, något som isåfall skulle trigga Oracles varning om ”orimligt hög SCN”, ORA-19706) och i sin tur stoppa varje ingående databas.

Då kommer vi till det stora kruxet – ytterligare en bugg. Den här buggen handlar om att ett visst backupkommando (ALTER DATABASE BEGIN BACKUP) får SCN att skjuta i höjden i mycket högre grad än vad den borde. Det riktigt luriga är att efter att backupen är klar (ALTER DATABASE END BACKUP) så fortsätter detta beteende. Kombinationen av många hopkopplade databaser plus hotbackup med kommandot ovan gör helt plötsligt att risken att komma över 16384 transaktioner per sekund inte ter sig så avlägsen.

För er säkerhetsmedvetna människor därute kan jag också påpeka att det räcker med höga rättigheter på enbart en av de ingående databaserna; ponera att jag har SYSDBA-rättigheter på en pytteliten databas som inte på något sätt är kritisk men ändå pratar med en eller flera andra (som i sin tur pratar med en eller flera andra, etc.). Här får jag utan invändning göra just ALTER DATABASE BEGIN/END BACKUP. Det får denna lilla databas SCN att dra iväg, och får således med sig de andra databaserna enligt reglerna om att det är det högsta SCN som är det som gäller. Således är det möjligt att se detta som en denial-of-service-attack om man är konspiratoriskt lagd.

Konsekvenserna av dessa problem sträcker sig från tappade transaktioner då SCN inte kan räknas upp som tänkt till kompletta drifstopp.

Idag finns patchar att tillgå för backupbuggen (bug 12371955: "High SCN growth rate from ALTER DATABASE BEGIN BACKUP in 11g)

och Oracle arbetar med att komma ut med publika patchar för själva grundproblemet. De lösningar som finns tillgängliga nu gör det möjligt att ändra multiplikatorn till något högre än 16384, men grundproblemet finns dessvärre kvar.

För att få tag på patchar måste man ha ett giltigt supportavtal med Oracle och tillgång till My Oracle Support (fd. MetaLink).

Summa summarum: i en (för Sverige) extremt ovanligt komplex miljö med hundratals hopkopplade databaser, som kör hotbackup med ALTER DATABASE BEGIN/END BACKUP finns risken för att stöta på ovan nämnda buggar. Konsekvenserna är enormt stora, men risken att drabbas är låg.

Följande artikelID på My Oracle Support tar upp problemet: 1393360.1

(detta är en Svensk översättning och omskrivning av en InfoWorldartikel från den 17e januari, se http://www.infoworld.com/d/security/fundamental-oracle-flaw-revealed-184163-0 för originalartikeln.)