2004/1/16付の mremap exploit で実行中のプロセスが死ぬ

前回は現象面だけを追ったが、少し気になったので今度はソースコードを見てみた。

vmscan.cは/usr/src/linux/mm/にある。kernel-2.4.22-0vl10のvmscan.cを見てみると、270行はswap_out_vmaという関数が該当する。

/* mm->page_table_lock is held. mmap_sem is not held */
static inline int swap_out_vma(struct mm_struct * mm,
 struct vm_area_struct * vma, unsigned long address, int count,
 zone_t * classzone)
{
        pgd_t *pgdir;
        unsigned long end;
                                                                                
        /* Don't swap out areas which are reserved */
        if (vma->vm_flags & VM_RESERVED)
                return count;
                                                                                
        pgdir = pgd_offset(mm, address);
                                                                                
        end = vma->vm_end;
        BUG_ON(address >= end); //←ここでエラー

(以下略)

この関数はさらにswap_out_mmという関数から呼ばれていて、そのときの引数addressにはvma->vm_start以上の値が入っている。このエラーが出るのは address >= vma->vm_end のときだから、vma->vm_start == vma->vm_endのときに問題になりそう。kernel-2.4.24-0vl2も見たけどこの部分のコードは同じだった。だからサイズ0のメモリ領域は作っちゃいけないものなんだろう。要するに、このエラーはサイズ0のメモリ領域をスワップアウトしようとしたときに起きるようだ。