2.4.24 - chyba?
Jirka Kosina
jikos na jikos.cz
Úterý Leden 6 02:51:13 CET 2004
On Mon, 5 Jan 2004, Martin `MJ' Mares wrote:
> > IMHO se to urcite tyka i 2.6. Jednak je to na te strance napsano :-)),
> Ono je na te strance napsano i to, ze se to tyka 2.2, ve ktere mremap
> vypada o hodne jinak a nikdo z kernelovych hackeru na linux-kernel listu
> zatim nevymyslel, jaky problem by ve 2.2 mohl nastavat :)
Ted jsem se v tom par desitek minut vrtal, a zatim mi neni prilis jasne
jak se da zero-length mapovani pouzit jinak nez na denial of service.
Puvodne jsem mel za to, ze jde o to, ze nektera z funkci, ktera prochazi
vsechny existujici vma daneho procesu, nebude pocitat s tim, ze muze
existovat mapovani nulove velikosti (bude misto toho pocitat mapovani
zarovnane na stranku), takze kdyz bude (pri fork()) toto mapovani
kopirovat, provede do forknuteho procesu kopirovani jedne stranky (4k u
userlandovych stranek), ktera se v parent procesu nevyskytovala - bude se
pravdepodobne jednat o nejaka nahodna data.
Z letmeho pohled do dup_mm() a copy_page_range() se mi vsak zda, ze
takove kopirovani by diky testu address >= end v copy_page_range() nemelo
probehnout.
Jedina stranka, o ktere jsem si puvodne myslel ze ma cenu uvazovat, je ta
zacinajici na adrese 0xC0000000, abysme trefili pri kopirovani alespon
nejaka zajimava data (kernelu) (coz je dalsi problem, protoze linuxovy
kernel na x86 na zapnute PSE, cili stranky v kernelu maji 4MB, takze to
prochazeni pagetables, ktere je naprogramovane na 4kb stranky by delalo
podivne veci ... ?).
Problem je, ze pri kopirovani pristup do takove stranky (diky neexistenci
mapovani) vyvola trojity vypadek stranky, a kernel se rebootuje (jak lze
ostatne snadno vyzkouset, napiseme-li si trivialni program, ktery vytvori
zero-length mapovani na adrese 0xC0000000 a pak udela fork()).
Pokud se testovaci program, ktery nekde vytvori zero-length mapovani,
neforkne, ale po vytvoreni mapovani (na libovolnem miste) skonci, dojde k
BUG()u v kernelu, protoze pri uklizeni mapovani ve funkci zap_page_range()
projde test na address >= end, coz vyvola onen BUG(), protoze je
evidentni, ze je mapovani nejake podivne.
Jedine dalsi co mne napada kudy by potencialne mohla vest nejaka cesta, je
pres munmap()ovani tohoto nuloveho mapovani - zda se mi totiz, ze munmap()
predpoklada, ze addr < vma->vm_end (dokonce je to napsano i v komentari,
mm/mmap.c, radek 938 (v 2.4.20)) ... ovsem opet mi zatim neni jasne jak
toto pripadne vyuzit k prepsani nejake citlivejsi pameti - i kdybychom
takhle teoreticky mohli zasahnout nekam ke hranici kernelu na 0xC0000000,
dostavame se zase k problemu s tripple faultem.
Ma nekdo nejake dalsi napady?
--
JiKos.
Další informace o konferenci Linux