ключевой фрагмент функции elf_core_dump(), подверженной переполнению
Типичное переполнение буфера! Программист объявляет знаковую переменную len (см. /* 1 */) и спустя некоторое время передает ее функции copy_form_user, копирующей данные из пользовательской памяти в область ядра. Проверка на отрицательное значение не выполняется (см. /* 2 */). Что это значит для нас в практическом плане? А вот что! Если current->
mm->
arg_start будет больше, чем current->
mm->
arg_end, в ядро скопируется очччень большой регион пользовательского пространства.
А как этого можно добиться? Анализ показывает, что переменные current->
mm->
arg_start и current->
mm->
arg_end инициализируются в функции create_elf_tables, причем если функция strnlen_user возвратит ошибку, то будет инициализирована лишь переменная current->
mm->
arg_start, а current->
mm->
arg_end сохранит свое значение, унаследованное от предыдущего файла.
static elf_addr_t *
create_elf_tables(char *p, int argc, int envc,
struct elfhdr * exec,
unsigned long load_addr,
unsigned long load_bias,
unsigned long interp_load_addr, int ibcs)
{
current->
mm->
arg_start = (unsigned long) p;
while (argc-->
0)
{
__put_user((elf_caddr_t)(unsigned long)p,argv++);
len = strnlen_user(p, PAGE_SIZE*MAX_ARG_PAGES);
if (!len || len >
PAGE_SIZE*MAX_ARG_PAGES)
return NULL; /* * */
p += len;
}
__put_user(NULL, argv);
current->
mm->
arg_end = current->
mm->
env_start = (unsigned long) p;
…
}