информационная безопасность
без паники и всерьез
 подробно о проектеRambler's Top100
Атака на InternetСтрашный баг в Windows
BugTraq.Ru
Русский BugTraq
 Анализ криптографических сетевых... 
 Модель надежности двухузлового... 
 Специальные марковские модели надежности... 
 Три миллиона электронных замков... 
 Doom на газонокосилках 
 Умер Никлаус Вирт 
главная обзор RSN блог библиотека закон бред форум dnet о проекте
bugtraq.ru / форум / site updates
Имя Пароль
ФОРУМ
если вы видите этот текст, отключите в настройках форума использование JavaScript
регистрация





Легенда:
  новое сообщение
  закрытая нитка
  новое сообщение
  в закрытой нитке
  старое сообщение
  • Напоминаю, что масса вопросов по функционированию форума снимается после прочтения его описания.
  • Новичкам также крайне полезно ознакомиться с данным документом.
#279 14.08.09 10:00  
Publisher: dl <Dmitry Leonov>
<"чистая" ссылка>
#279



#279, 14.08.2009
Локальное повышение привилегий в ядрах всех Линуксов
dl // 14.08.09 02:08
Если точнее, затрагивает все ядра 2.4 и 2.6, восходя аж к 2001 году. Связано с тем, что ряд функций ядра, наподобие sock_sendpage, не занимается проверкой полученного указателя на NULL, полагаясь на то, что соответствующие указатели будут корректно проинициализированы в обертках - таких как sock_no_sendpage. Однако в случае с sock_sendpage ошибка в макросе SOCKOPS_WRAP все же может привести к передаче в функцию нулевого указателя. Что и приводит к возможности внедрения кода, выполняющегося с правами ядра - достаточно положить его в нулевую страницу памяти. Патч уже доступен.
Замечу, что сама возможность подобного лихого обращения с нулевыми указателями в современной ОС вызывает некоторое недоумение - к примеру, в архитектуре Win32/64 подобные плюхи принципиально невозможны по причине блокировки любого доступа к адресам с 0x0 по 0xFFFF (0xFFF в случае Win'9x).
Источник: cr0 blog [ http://blog.cr0.org/2009/08/linux-null-pointer-dereference-due-to.html...

Полный текст
:Замечу, что сама возможность подобного лихого обращения с... 18.08.09 12:45  
Автор: Harbour Статус: Незарегистрированный пользователь
<"чистая" ссылка>
:Замечу, что сама возможность подобного лихого обращения с нулевыми указателями в современной ОС вызывает некоторое :недоумение - к примеру, в архитектуре Win32/64 подобные плюхи принципиально невозможны по причине блокировки любого :доступа к адресам с 0x0 по 0xFFFF (0xFFF в случае Win'9x).

................ from linux config .........................

CONFIG_DEFAULT_MMAP_MIN_ADDR:

This is the portion of low virtual memory which should be protected
from userspace allocation. Keeping a user from writing to low pages
can help reduce the impact of kernel NULL pointer bugs.
For most ia64, ppc64 and x86 users with lots of address space
a value of 65536 is reasonable and should cause no problems.
On arm and other archs it should not be higher than 32768.
Programs which use vm86 functionality would either need additional
permissions from either the LSM or the capabilities module or have
this protection disabled.
This value can be changed after boot using the
/proc/sys/vm/mmap_min_addr tunable.
...................................................................

В Линуксе все пучком с доступом к 0 странице баг в том что эту проверку в одном случае можно было обойти Теперь уже нельзя ж)
Какие проверки, зачем? 18.08.09 13:38  
Автор: HandleX <Александр М.> Статус: The Elderman
Отредактировано 18.08.09 13:40  Количество правок: 2
<"чистая" ссылка>
В винде страница памяти с нулевым адресом едина для всех процессов и любое обращение к ней -- чтение, запись, исполнение -- ВСЕГДА вызывает Access Violation аппаратурой процессора. Хоть запроверяйся -))
Ну и эта. Вы абсолютно уверены, что это "единственное место", где подобное было возможно в линуксе?
Ты это так говоришь, как будто системы без дыр теоретически... 18.08.09 17:50  
Автор: Zef <Alloo Zef> Статус: Elderman
<"чистая" ссылка>
> Ну и эта. Вы абсолютно уверены, что это "единственное
> место", где подобное было возможно в линуксе?

Ты это так говоришь, как будто системы без дыр теоретически возможны. Выход тока один: менше кода - меньше дыр.
Мдя. Ты таки ничего не знаешь о программировании 18.08.09 20:47  
Автор: amirul <Serge> Статус: The Elderman
<"чистая" ссылка>
> Ты это так говоришь, как будто системы без дыр теоретически
> возможны. Выход тока один: менше кода - меньше дыр.
Один? Уверен? То есть квалификация программистов, использованная методология разработки (да хоть бы отдельные ее части типа покрытия тестами, в том числе и fuzzy) влиять на количество "дыр" (в частности снизить) не могут?
"Задача останва" неразрешима теоретически. 19.08.09 04:29  
Автор: Zef <Alloo Zef> Статус: Elderman
<"чистая" ссылка>
Доказано, что начиная с некоего уровня сложности теоретически не может быть алгоритма, способного проверить программу на отсутствие глюков иначе, как полным перебором всех аргументов.

Отсюда однозначный вывод, что главным фактором снижения вероятности ошибки является снижение сложности и объема кода, тем более, что увеличение объема занимаемой памяти повышает вероятность лучайного ее сбоя.
При тестировании программ сам код практически никогда не анализируется, анализируется вывод программы в пределах тестового покрытия входных значений. И ваще это всё оффтопик. 19.08.09 12:24  
Автор: HandleX <Александр М.> Статус: The Elderman
Отредактировано 19.08.09 12:33  Количество правок: 3
<"чистая" ссылка>
А вернувшись к теме ветки, можно отметить, что создание общей для всех процессов недоступной страницы памяти в районе нулевого адреса -- зачёт NTшным архитекторам, не лохи ядро писали ;-)
Страница единожды создана, работает (попробуй, обратись к ней!), и больше жрать не просит.

А линуксячья константа границы нижнего адреса и проверка этой границы ПРИ КАЖДОМ создании объекта отображения памяти в виртуальном адресном пространстве линуксячьих процессов -- низачот, хотя бы потому, что постоянно нужно что-то проверять программному коду функции, а не железяке-процессору.

Вот такое ИМХО.
строго говоря, она даже и не создана, а просто неотмаплена на реальную память 19.08.09 15:05  
Автор: dl <Dmitry Leonov>
<"чистая" ссылка>
Так что вся защита получается сама собой, просто и элегантно. В линуксах, как я понял из обсуждений, сейчас обычно так же, но из не очень понятных соображений совместимости дали возможность опустить границу отмапленной памяти до нуля - вроде при установленном WINE такое дело вылезает.
Могу ошибаться, но помниться мне, что ядро защищено на... 19.08.09 16:53  
Автор: Den <Denis> Статус: The Elderman
<"чистая" ссылка>
Могу ошибаться, но помниться мне, что ядро защищено на уровне привелегий страниц памяти и находится на страницах, с уровнем привелегий "супервизор". Эти страницы мапятся в адресное пространство всех приложений, работающих с привелегиями "пользователь" (соответствует третьему кольцу защиты) в собственных контекстах и собственных адресных пространствах. Соответсвенно, любое обращение из приложения с уровнем "пользователь" к странице с уровнем "супервизор" вызывает общую ошибку защиты. Подобные вызовы возможны только через системные вызовы (шлюзы вызовов).
Все верно, но в данном случае речь не об этом. 19.08.09 20:51  
Автор: amirul <Serge> Статус: The Elderman
<"чистая" ссылка>
Просто первые 64к линейных адресов (16 страниц на x86/x64) имеют сброшенный бит P (present) в своих PTE. Во всех процессах. Ну и так как разметка адресного пространства неизменна для процесса в каком бы режиме (user/supervisor, а точнее CPL==3/CPL==0 для x86) ни исполнялся его тред - меняются только селекторы (которые и в юзере и в ядре - флетовые), то одна и та же пачка недоступных страниц аппаратно дает отлуп любому разыменованию null-pointer-ов.
Очень похоже, что эти 64Кб отведены на поддержку схемы... [fix] 20.08.09 01:10  
Автор: Den <Denis> Статус: The Elderman
Отредактировано 20.08.09 01:16  Количество правок: 2
<"чистая" ссылка>
Очень похоже, что эти 64Кб отведены на поддержку схемы адерсации (каталог таблиц страниц, GDT системы и IDT) и никак не связаны с нулевым указателем.
Причем здесь GDT/IDT? Физические адреса несколько отличаются от линейных, ага 20.08.09 02:25  
Автор: amirul <Serge> Статус: The Elderman
<"чистая" ссылка>
> Очень похоже, что эти 64Кб отведены на поддержку схемы
> адерсации (каталог таблиц страниц, GDT системы и IDT) и
> никак не связаны с нулевым указателем.
Отлов разыменований нулпоинтеров - ЕДИНСТВЕННОЕ предназначение той дырки в адресном пространстве.
Естественно! Только не путай сегментацию со страничной... 20.08.09 12:14  
Автор: Den <Denis> Статус: The Elderman
<"чистая" ссылка>
> Причем здесь GDT/IDT? Физические адреса несколько
> отличаются от линейных, ага

Естественно! Только не путай сегментацию со страничной организацей. У дескриптора страницы отсутствует поле базового адреса, ага?
Все сегменты в ядре NT имеют базу 0.

> > Очень похоже, что эти 64Кб отведены на поддержку схемы
> > адерсации (каталог таблиц страниц, GDT системы и IDT)
> и
> > никак не связаны с нулевым указателем.

> Отлов разыменований нулпоинтеров - ЕДИНСТВЕННОЕ
> предназначение той дырки в адресном пространстве.

Для этого не обязательно отслеживать обращение к 16-ти страницам, достаточно только к одной - к первой страницы первого каталога.
64Кб как раз максимальный размер таблицы дескрипторов сегментов. Почти уверен, что место полностью отведено под IDT, хранящую дескрипторы шлюзов ловушек прерываний.
Я? Путаю? Да не может такого быть! :-) 20.08.09 13:22  
Автор: amirul <Serge> Статус: The Elderman
<"чистая" ссылка>
А если серьезно, я просто думал, что gdtr/idtr тоже содержат физические адреса. Ошибся, но нулевые адреса от этого не стали использоваться для чего то кроме отлова нулевых указателей.

> > Причем здесь GDT/IDT? Физические адреса несколько
> > отличаются от линейных, ага

> Естественно! Только не путай сегментацию со страничной
> организацей. У дескриптора страницы отсутствует поле
Выше

> Все сегменты в ядре NT имеют базу 0.
Не все :-P
Но не суть. Мы сейчас говорим именно о флетовых сегметах (да в общем о любых, которые позволяют обратиться к ЛИНЕЙНОМУ адресу 0).

> > > Очень похоже, что эти 64Кб отведены на поддержку
> схемы
> > > адерсации (каталог таблиц страниц, GDT системы и
> IDT)
Каталог страниц всю жизнь начинался с C0000000. Да и вообще крайне логично не держать в юзерских адресах вообще ничего критичного, а до ядерных адресов "не достают" юзерские селекторы.
Ну провел небольшой тест:
kd> dd nt!KiAbiosGdt l poi(nt!KeNumberProcessors)
80551ee0  8003f000

---

KiAbiosGdt - это такая табличка, в которой хранятся базовые адреса для gdt для всех процессоров.

Ну еще и такое писал:
int
main() {
	long gdt = 0, idt = 0;
	__asm {
		sgdt gdt
		sidt idt
	}
}

---
Тоже выдает старшие адреса

kd> !pte 0
               VA 00000000
PDE at 00000000C0600000    PTE at 00000000C0000000
contains 0000000002AB0067  contains 0000000000000000
pfn 2ab0 ---DA--UWEV

---
Нет там ничего. Для него даже PTE нет.

> > > никак не связаны с нулевым указателем.
Только с ним и связаны. Там вообще памяти нет.

> > Отлов разыменований нулпоинтеров - ЕДИНСТВЕННОЕ
> > предназначение той дырки в адресном пространстве.
>
> Для этого не обязательно отслеживать обращение к 16-ти
> страницам, достаточно только к одной - к первой страницы
> первого каталога.
А давно ли все структуры данных стали меньше 4к?
struct Data {
    int padding[10000];
    int field;
};

struct Data *data = (struct Data *)NULL;
data->field = 1;

---

Можно было бы и больше зарезервировать, но 64к кажется достаточно большим, чтобы отловить подавляющее большинство структур

> 64Кб как раз максимальный размер таблицы дескрипторов
> сегментов. Почти уверен, что место полностью отведено под
> IDT, хранящую дескрипторы шлюзов ловушек прерываний.
Зря уверен. Там нет памяти. Вообще. MEM_FREE. Np. Да и с чего бы хранить такую важную инфу в юзерском адресном пространстве?
Ну м.б. Тебе видней... ;) 20.08.09 21:41  
Автор: Den <Denis> Статус: The Elderman
Отредактировано 22.08.09 03:04  Количество правок: 1
<"чистая" ссылка>
[upd]
> А если серьезно, я просто думал, что gdtr/idtr
> тоже содержат физические адреса. Ошибся,
> но нулевые адреса от этого не стали
> использоваться для чего то кроме отлова
> нулевых указателей.

Почему ошибся? Так и есть! Иначе как бы они указывали на местонахождение таблицы?
Нет уж. Ошибся так ошибся 22.08.09 11:41  
Автор: amirul <Serge> Статус: The Elderman
<"чистая" ссылка>
> Почему ошибся? Так и есть! Иначе как бы они указывали на
> местонахождение таблицы?
Собственно
http://www.intel.com/Assets/PDF/manual/253666.pdf

LGDT/LIDT—Load Global/Interrupt Descriptor Table Register
Description
Loads the values in the source operand into the global descriptor table register
(GDTR) or the interrupt descriptor table register (IDTR). The source operand specifies
a 6-byte memory location that contains the base address (a linear address) and
the limit (size of table in bytes) of the global descriptor table (GDT) or the interrupt
descriptor table (IDT).
...

Базовый адрес GDTR/IDTR линейный. Это cr3 (база PD) - физический.
Все верно! Это я торможу... Давно не перечитывал архитектуру. 22.08.09 15:15  
Автор: Den <Denis> Статус: The Elderman
<"чистая" ссылка>
Ага. Вот и я точно так же стормозил. После того как ты меня исправил - полез в мануал :-) 23.08.09 01:11  
Автор: amirul <Serge> Статус: The Elderman
<"чистая" ссылка>
Не фик писать программы, которые обращются по нулевому... 20.08.09 01:00  
Автор: DPP <Dmitry P. Pimenov> Статус: The Elderman
Отредактировано 20.08.09 01:03  Количество правок: 1
<"чистая" ссылка>
Не фик писать программы, которые обращются по нулевому адресу, тогда будет фиолетово никсы ли это или винда.
Ладно бы эти события бы еще нормально обрабатывались, а то вылазит на экран "бла бла бла, нул поинтер асижмент...", да и все прочее ненавижу вместе с хексадецимальным дампом, регистрами, кодами эксцепшнов, стеком вызова функций с их кривыми названиями и отсылкой сообщений разработчикам проги или даже в сам микрософт. Ладно б позвонить в хелпдеск, продиктовать, что вылезло, а там экс-студент-красное_ухо быстро б сказал в чем беда. Нет, блин, 99% никого не интересуют эта абракадабра. Нет бы просто и тупо "сам дурак, смотри, что написал: ...", "добавь памяти в комп" или "писатели таких-то дров казлы".
Ага. Если все люди станут в большой круг и возьмутся за руки, то никто не сможет сжать руку в кулак 20.08.09 02:37  
Автор: amirul <Serge> Статус: The Elderman
<"чистая" ссылка>
> Не фик писать программы, которые обращются по нулевому
> адресу, тогда будет фиолетово никсы ли это или винда.
Есть факт: программы часто лезут "не туда", и по нулевому указателю - чаще всего. Система просто обязана с этим что то сделать.

> Ладно бы эти события бы еще нормально обрабатывались, а то
Кстати, они вполне нормально отлавливаются тем же SEH-ом (более того, проверка доступности адреса на чтение или запись, это собственно попытка чтения/записи с SEH-оберткой).

> вылазит на экран "бла бла бла, нул поинтер асижмент...", да
> и все прочее ненавижу вместе с хексадецимальным дампом,
Ядерные падения создают краш-дамп, который можно либо поанализировать самому, либо отослать разработчикам. Юзермодовые - там доктор ватсон заправляет. Его можно заменить (или скидывать юзерские дампы прямо из Task Manager-а), но я особо никода этим не занимался.

> быстро б сказал в чем беда. Нет, блин, 99% никого не
> интересуют эта абракадабра. Нет бы просто и тупо "сам
Кстати, да. Меня вообще не интересует содержимое дрватсоновского лога или заботливо переписанные на листик цифры с синего экрана: зачем мучаться если есть крешдампы?

> дурак, смотри, что написал: ...", "добавь памяти в комп"
> или "писатели таких-то дров казлы".
Чаще всего: "Извините, мы не можем воспроизвести Вашу проблему" :-)
1  |  2 >>  »  




Rambler's Top100
Рейтинг@Mail.ru


  Copyright © 2001-2024 Dmitry Leonov   Page build time: 0 s   Design: Vadim Derkach