Цитата(Demeny @ Nov 29 2007, 05:22)

На уровне Kernel (RING0) никакой "Винды" уже практически нет - и некому "схватить за руку" зарвавшееся приложение. Привожу простой пример. Драйвер ожидает, что устройство должно прислать ему 13 байт - он выделяет буферную переменную на 13 байт. Где ? Правильно, на стеке, переменная-то локальная. А устройство, собака, прислало не 13 байт, а 14. Куда девался лишний байт ? Записался куда-то туда же на стек. Что ещё хранится на стеке ? Адрес возврата из процедуры, верно ? Значит, лишний байт запросто мог снести адрес возврата из процедуры. Куда улетит процессор после возврата из процедуры - очень вероятно, что на перезагрузку. Иногда куда-то туда, где его ещё могут тормознуть силы операционной системы, сгенерить исключение, выдать знаменитый BSOD ... Но увы, не всегда.
В User-mode такой прыжок просто приведёт к исключению (Access Violation) - и приложение будет с позором выдворено из системы. А на уровне ядра на исключения не всегда приходится рассчитывать, особенно в процедурах обработки прерываний, где код драйвера выполняется на высоких приоритетах ...
Стоп, стоп! Уважаемый колега. Давайте не спеша пройдемся по механизму получения данных от устройств.
Допустим, драйвер создает переменную размереом 13 байт на стеке. Далее следует процесс копирования в нее 14 байт. Я хотел бы более подробно остановиться на этом.
Есть, собственно, два мехпанизма копирования -- аппаратный и программный. Рассмотрим оба. Для начала рассмотрим аппаратный, как наиболее вероятный. (К сожалению, я точно не знаю, что там конкретно происходит. Надеюсь, что знающие люди поправят.)
Итак, ПДП. Мы заказываем контроллеру ПДП 13 байт и получаем из южного моста посылку в 13 байт и аппаратное прерывание о том, что данные получены. Тринадцать байт -- ни больше, ни меньше. Так устроен ПДП. Что же касается 14-го байта, то он остается в аппартном буфере моста. Возможно, он помешает при следующем копировании. Но самое главное, ни о каком превышении размера, ни о каком "выезде" за границы массива, нет и речи. Стек цел и невредим. Еще раз повторю, что мне кажется, именно так и происходит получение данных от устройства в драйвер винды.
Второй способ, прграммный. (Скорее всего так не делается.) Драйвер сам бегает за каждым байтом в аппаратный порт и складывает полученные байты в массив, который на стеке. Т.е. все делается программно. Разумеется очень медленно. Отсюда вопрос: а что, слабо было разработчикам драйвера воткнуть проверку границ? Решили сделать быстро-оисполняющийся код за счет проверки? -- Так это вообще глупо -- по одному байту выкачивать инфу. Более вероятно, что просто позабыли.
Хорошо. Продожаем. Что делать, если в драйвере возникла такая ситуация? Ронять ОСь? Может просто передать "на верх" состояние ошибки? Для этого у драйверов есть мехнизм. Какие проблемы?
Мне кажется, что все-таки корень проблемы лежит не в нарушении стека, а где-то в области динамической подгрузки драйверов нижнего уровня. Что-то там видимо разработчики накосячили. А может просто сам механизм динамической загрузки не отработан.
Тема интересная. Если есть что сказать, говорите. А я сейчас наверно попытаюсь выкроить время -- полезу в книжку разбираться.
Цитата(Harbour @ Nov 29 2007, 12:01)

Теоретически [

] такие глюки возможны и в Linux'е, вопрос в том что они будут моментально отловлены и менее чем за сутки будет выпущено исправление, дабы оное безобразие никогда больше не повторилось. Любителям остальных ОС можно порекомендовать техподдержку

Извините, коллега, вопрос не в том, что "за сутки или за пол-года".
Вопрос в том --
реально (не теоретически!) наблюдаются-ли в других ОСях (в Linux'е, в частности) такие же явления с USB-устройствами?