почему пишут небезопасный код

Landstreicher

Практическую каждую неделю находится уязвимость в каком-нибудь важном распространенном сервисе (например, samba, named, binfmt_elf в Linux, MS-RPC в Windows итп). Ошибка обычно на редкость тупа - объявляется какой-нибудь char buf[256] и в него делается sprintf(buf, "%s", user_data). Фишка в том, что все эти штуки давно изучены. Хорошо известно, что так делать нельзя. Мало того, это везде пишут (я бы даже сказал кричат это рассказывают на лекциях итп. И тем не менее ошибки допускаются. Безусловно, разработчики Samba или ядра Linux - очень квалифицированне люди. Безусловно, знают что так делать нельзя, что это может привести к проблемам с безопасностью. И тем не менее, такие ошибки постоянно делаются. В тоже время решение проблемы очевидно - написать какой-нибудь класс string определить в нем функции printf, insert, operator =, == итп. Это даже облегчит написание программы, внесет ясность в нее. В C++ например есть std::string, во многих других языках (Perl, Python, Java) тоже есть string. Можно например в С-программу внести string и не использовать других возможностей C++. Тем не менее так никто не делает. То есть должна быть какая-то объективная причина, принуждающая людей знающих что так делать нельзя, тем не менее писать плохой, подверженнный ошибкам код. В чем она состоит?
PS. Просьба не считать это флудом, или критикой в адрес разработчиков. Мне просто интересны реальные причины столь плачевного состояния в области надежности и безопасности.

otvertka07

неудобно классом этим пользоваться, или может лень, потому что остальные функции работают с _TCHAR*
некрасивый код получается

Landstreicher

неудобно в целом или менее удобно чем char *? Если второе - то пожалуйста пример, что умеет char *, что не умеет string
вообще я имел ввиду некий абстрактный класс string (не обязательно std::string из STL). его можно один раз написать и отладить, и затем навсегда забыть про buffer overflow - по-моему этого того стоит.
если утверждается, что невозможно вообще написать класс типа string который было бы удобно использовать, то тут тоже нужны объяснения, мне это например совсем не очевидно

smnikiforov

>В чем она состоит?
обычная лень

Marinavo_0507

> объявляется какой-нибудь char buf[256] и в него делается sprintf(buf, "%s", user_data)
ты именно про самбу говоришь?
когда я последний раз туда смотрел, там все такие фунции приводили к чему-то вроде "#error ибо нех"
> Мало того, это везде пишут (я бы даже сказал кричат это рассказывают на лекциях итп.
распространённых сценария два:
1) ничего не читать, и тем более лекции не слушать:
что тут думать, трясти надо -- ну т.е. работу работать
2) вносят заведомо проблемный код, чтоб побыстрее получить нечто рабочее и пригодное к тестированию,
в надежде потом заменить на правильный, а потом забыл/лень/дедлайн.

Landstreicher

> ты именно про самбу говоришь?
нет, в целом. одинаковые ошибки находят в совершенно разных программах написанных различными людьми. samba - как пример недавно найденной уязвимости.
> когда я последний раз туда смотрел, там все такие фунции приводили к чему-то вроде "#error ибо нех"
это уже интересно. то есть там применяются какие-то автоматические средства для борьбы с такими штуками? где можно про это подробнее узнать?
если такие средства есть, почему их неиспользуют во всех остальных программах?
> что тут думать, трясти надо -- ну т.е. работу работат
как-то я сомневаюсь, что люди ботающие linux и samba уж совсем ничего не знают. вряд ли такое возможно.
> а потом забыл/лень/дедлайн
вот это гораздо более вероятная причина. хотя надо признать это несколько неутешительный результат. скажем как бороться с багом в компиляторе еще более-менее понятно, а как бороться с этим фактором - хз.
есть ли какие-нибудь еще причины или это единственная?

Marinavo_0507

> то есть там применяются какие-то автоматические средства для борьбы с такими штуками?
там был всего лишь список стандартных функций, которыми запрещено пользоваться
> как-то я сомневаюсь, что люди ботающие linux и samba уж совсем ничего не знают
одно дело - слышать что такое бывает, а другое - постоянно следить, не случилось ли это с тобой

lenabarskaya

std::string - медленная штука по сравнению с фиксированным буфером. Особенно при неразумном использовании.

mirt1971

Хмммм... Ну я тоже иногда так делаю. Пишу char buf[1000]; int i = 0; sprintf( buf, "%d", i );
Я так делаю только в том случае если уверен что места хватит. Конечно никаких "%s". это втопку.
Про ядро линукс - там же нельзя использовать с++(хотя в последнее время стало немножко можно )

myrka68

там ещё ostringstream есть

mirt1971

Есть. Только он довольно медленный. Когда нужна скорость - то лучше использовать snprintf с хорошо подобранным буфером и malloc(2*n).

lenabarskaya

Когда нужна скорость, malloc лучше вообще не использовать

Landstreicher

> std::string - медленная штука по сравнению с фиксированным буфером. Особенно при неразумном использовании.
Это так просто утверждение? Или ты читал исходник, писал benchmark-и, анализировал? Если да - то результаты в студию.
Сам я бенчмарков не гонял, но читали исходники и мне кажется, что при хорошем компиляторе C++ скорость работы std::string будет отличаться от char * лишь на небольшие проценты (имеется ввиду реализация STL из GNU C++). В целом, я не вижу причин, почему переход с char* на string должен заметно замедлять программу. У объявлений char buf[1024] тоже ведь есть свои минусы - например, сильно жрется стек и он может кончится при рекурсии. Чем больше стековый фрейм, тем дальше друг от друга аргументы - тем хуже попадание в кэш. В g++ например sizeof(string)=4.
А кроме того, предположим что программа стала работать на 5% медленнее, но зато из нее исчезли все потенциальные buffer overflow. Да любой разработчик с руками такое оторвет!

mirt1971

А что лучше использовать?

Landstreicher

sprintf и snprintf - две большие разницы. c snprintf все более-менее понятно, он проблем не вызывает

mirt1971

Смотря в каких операциях. И еще это зависит от компилятора. Для шаблонов gcc генерит отвратительный код. Пример: у меня была функция умножения матриц. в ней я не поменял ни строчки. Только тип double заменил на A. И сделал как шаблон template< class A >. Скорость упала на 30%. Вот так.

mirt1971

А где ты в том посте нашел snprintf?

lenabarskaya

Пользуешься std::string - аллоцируешь память в куче. Пользуешься неразумно (а к этому все склонны) - аллоцируешь память несколько / много раз. Куча - тормоз. В многопоточных приложениях - сильный тормоз.
Можно бороться. Старательно прикидывать, что влечёт каждая операция над строками, писать хитрые аллокаторы, не пользующиеся общей кучей, и т.д. Мне лично в таких случаях проще использовать (если возможно) фиксированный буфер.
Написание класса строки с хорошей производительностью - это "challenging task". Можешь интереса ради поковыряться в реализациях basic_string в разных STL и т.п.. Думаю, много интересного найдёшь. Например, некоторые товарищи для строк меньше определённой длины используют embedded buffer в объекте, а если не хватает - тогда лезут в кучу, и т.п.

shlyumper

В C++ например есть std::string, во многих других языках (Perl, Python, Java) тоже есть string. Можно например в С-программу внести string и не использовать других возможностей C++.

тырык пырык.
И каким же это способом, интересно мне знать, внесение std::string в программу повышает ее защищенность от buffer overflow?
Я, наверное, отстал от жизни, но мне почему-то казалос, что функции из libc/glibc не имеют никакого представления о том, что такое std::string, следовательно обмен информацией с этими функциями все равно всегда будет оставаться на уровне sprintf и т.п. В чем же мега profit?

Landstreicher

> Пользуешься std::string - аллоцируешь память в куче. Пользуешься неразумно (а к этому все склонны) - аллоцируешь память несколько / много раз. Куча - тормоз. В многопоточных приложениях - сильный тормоз.
Безусловно, все это так. Но, если мы работаем через char *, то у нас те же самые проблемы. Если мы хотим обрабатывать некий user_data который потенциально может быть любого размера, то мы вынуждены выделять память под него руками. То есть вызывать malloc/strdup. Он выделяет память в такой же куче, и точно так же создает проблемы в многопоточной среде. В реализациях STL от GNU C++ дефолтный operator new вызывает malloc, так что там это вообще одно и то же.
Проблемы здесь - общие, они есть и при работе со string и char *. Предлагаю рассматривать их как неизбежное зло. Важно, что сам по себе string не вносит больших накладных расходов.
> Написание класса строки с хорошей производительностью - это "challenging task". Можешь интереса ради поковыряться в реализациях basic_string в разных STL и т.п..
> Думаю, много интересного найдёшь. Например, некоторые товарищи для строк меньше определённой длины используют embedded buffer в объекте, а если не хватает - тогда лезут в кучу, и т.п.
Согласен. Но даже так - неужели нельзя было бы собраться один раз и написать его. Перспектива уничтожения 90% buffer overflow очень заманчива.

Landstreicher

Идея в том, что большинство buffer overflow возникают в пользовательском коде. Если там пользоваться string, то операции типа sprintf не будут ничего портить. А если вдруг потребовалось вызвать функцию libc - использовать c_str

shlyumper

Идея в том, что большинство buffer overflow возникают в пользовательском коде.

Было бы неплохо такие идеи подкреплять примерами найденных и устраненных ошибок. ИМХО в пользовательском коде чаще всего такого рода ошибки возникают чаще всего на стыке libc и пользовательского кода, причем на пути "обратно" (из libc в пользовательский код а не на пути "туда" (где можно использовать c_str.

Ivan8209

Почти всегда --- из-за сей.
---
...Я работаю антинаучным аферистом...

Marinavo_0507

кстати последний buffer overflow в smbd, как я понял, случался при заполнении буфера для сообщения в бинарном формате,
так что строки тут вообще не при делах

evgen5555

Безусловно, разработчики Samba или ядра Linux - очень квалифицированне люди.
Читаль и плакаль...

evgen5555

Во-вторых, никто, кроме ахтоха юникод-мультибайт не упоминал.

stm7884696

ИМХО - просто так выгоднее с маркетинговой точки зрения... Если бы все работало - многие люди остались бы без работы.....

otvertka07

да забей, я думаю, DEP решит эту проблему

Marinavo_0507

Department of Environmental Protection?

otvertka07

ггг, web page

Marinavo_0507

есть несколько приёмов для написания эксплойтов, обходящих такую защиту

mirt1971

Это типа PAX что-ли? Да. Молодцы Майкросакс. Быстро среагировали.

garikus

http://www.inr.ac.ru/~info21/blackbox/disciplina/arr_bounds_checks.htm
Согласен, немного не в тему

garikus


Вопрос: Почему столь важный продукт, как операционная система, используемая на сотне миллионов компьютеров во всем мире, строится на столь гнилом фундаменте, как язык программирования, для которого нельзя написать компилятор, генерирующий эффективный и безопасный код, с тем чтобы переложить тривиальный механический труд по нудной проверке индексов массивов с человека, которому свойственно ошибаться при выполнении механических процедур, на компьютер, который именно для таких процедур и придуман?
Ответ: Потому что подавляющее большинство программистов Майкрософт, начиная с Билла Гейтса, — как бы хорошо ни была организована их работа и какими бы талантливыми индивидуумами они ни были сами по себе — классические программисты-самоучки, втянутые в круговорот компьютерной революции большими деньгами и задумывающиеся о методологии программирования только под сильной угрозой со стороны конкурентов.

Marinavo_0507

А типа есть компилятор какого-либа языка, который сам докажет отсутствие выхода за границы массивов в реализациях хотя бы таких алгоритмов, как:
1) бинарный поиск
2) быстрая сортировка
Чтобы не вставлять проверки времени выполнения на каждый доступ.

bleyman

Обожаю читать такую фигню.
Вот попрогаю на шарпе немножко, а потом ну давай такую фигню читать. Настроение поднимает што твой песдетс.
Кстати, все в курсе, что верхний уровень лонгхорна (Ну типа все, что чуть-чуть ниже АПИ) будет манагед?

bleyman

Кстати, а причем тут вообще М$? Разные всякие линухи вообще пишут любители, причем на С...
2Гадфазер: ну щаз типа посмотрю на .нет, как он там это все устроит.

garikus

> Кстати, а причем тут вообще М$?
частный случай

bleyman

Покажи пальцем на людей, пишуших операционки на языках, допускающих проверки вылета за границы массивов. В рантайме. И скажы ХА-ХА-ХА.
Я проверил, бтв. В бинарном поиске верхняя граница проверяется один раз на итерацию, нижняя не проверяется.

Marinavo_0507

> Покажи пальцем на людей, пишуших операционки на языках, допускающих проверки вылета за границы массивов.
Если под словом "операционка" понимать ядро, то я знаю вот:
http://www-2.cs.cmu.edu/~fox/
> В бинарном поиске верхняя граница проверяется один раз на итерацию.
Вот. А нужно вообще не проверять, максимум один раз на поиск.
> нижняя не проверяется
Потому что тип индекса - unsigned?
Попробуй signed.
P.S. ещё есть забавные штуки - arithmetic overflow.

sergey_m

Прочитал весь тред. Как-то все сфокусировались на строковых переполнениях. Но ведь это не единственная уязвимость.
Моё мнение по поводу поставленного Алексом вопроса такое: проблема в том, что большинство людей не умеют смотреть на свой код критически. Знакомый код они читают проглатывая целые блоки, не задумываясь о деталях. Наверное все сталкивались, что научрук находит в курсовой кучу опечаток, хотя вы сами прочитали её перед этим три раза. Поэтому всякая команда разработчиков должна уделять время рассматриванию чужого кода внутри команды. Разработчик A читает код разработчика Б и наоборот. К сожалению человеческая лень зачастую делает этот процесс чисто формальным и безответственным. С этим можно и нужно бороться. А вот бороться с проблемой анализа собственного кода по-моему намного тяжелее. Обычно получается взглянуть на свой код критически и вдумчиво только по прошествии некоторого времени.

sergey_m

Кстати, а причем тут вообще М$? Разные всякие линухи вообще пишут любители, причем на С...
Я фигею от понтов. И винду пишут самоучки, и линукс любители. А где же профессионалы? В хакерских командах? В ЦРУ и ФСБ? Или все в этом форуме?

Marinavo_0507

> А где же профессионалы?
Два ответа:
1) их нет, или почти нет (которые есть, работают над проектами, где важна надёжность любой ценой, т.е. в основном военные заказы)
2) профессионалами называют тех самых самоучек

garikus

Наверное, где-то в этом направлении :-)
Они есть, но их мало.
Вот ещё интересная ссылка:
http://www.inr.ac.ru/~info21/greetings/wirth_doklad_rus.htm
Думаю, стоит почитать, что там вообще пишут.

sergey_m

Есть специальный термин - life critical systems. Типа софт для самолетов, спутников и все такое
Хе-хе. Как раз сегодня в закрытом списке рассылки FreeBSD несколько товарищей хвастались тем, что применяют FreeBSD на аэродромах и в черных ящиках самолётов.

sergey_m

> Наверное, где-то в этом направлении :-)
Это была шутка?

Marinavo_0507

> Как раз сегодня в закрытом списке рассылки FreeBSD несколько товарищей хвастались тем,
> что применяют FreeBSD на аэродромах и в черных ящиках самолётов.
Вот я думал, писать ли про такое.
У Шнайера я тоже читал, как mainstream проникает в life critical projects, с соответствующими последствиями для безопасности и надёжности.
Законы рынка, хуле. Вероятность, что самолёт упадёт, несколько повысится, но зато сколько сэкономишь.
C оружием - ещё прикольнее.
Типа разработает враг первым оружие нового поколения, на несколько лет раньше, за счёт того, что поставили windows, а не создавали супер-надёжный специализированный код, и пофиг, что в боевых условиях он с большой вероятностью сглючит -- на учениях-то всё будет работать, и правительство другой страны прикажет своим быстро-быстро разработать аналог, и ниибёт. А значит, а на аналоге будет mainstream OS.

sergey_m

Опять же, не легенда ли что существуют супер пупер системы не доступные простым смертным? Какая-то теория заговора . Я честно говоря, в это не верю.
Еще пример из жизни: на МНПЗ, автоматизированный цех по производству полипропилена работает под управлением VMS. Там высокотоксичные реагенты, в больших количествах при высоком давлении и температуры. Авария будет локальной экологической катастрофой.

Marinavo_0507

> Опять же, не легенда ли что существуют супер пупер системы не доступные простым смертным?
Ну не совсем то, но всё же посмотри на список систем, сертифицированных на уровни безопасности B1 и выше Оранжевой Книги.
О скольки из них ты слышал в каком-нибудь другом контексте?
А для спутников и самолётов - так там и ОС не было, так как софт такой сложности не научились люди делать надёжным.
Недавно вот про Pioneer 10 модно было писать, в связи с тем, что он куда-то очень далеко улетел. В том числе и про софт его набортный рассказывали, поищи, если интересно, у меня ссылок не сохранилось.

sergey_m

поищи, если интересно, у меня ссылок не сохранилось.
Короче, за такое в этом разделе буду плюсовать. Это касается тебя и КОНТРЫ. Не можешь найти сам - не пиши.

sergey_m

Ну не совсем то, но всё же посмотри на список систем, сертифицированных на уровни безопасности B1 и выше Оранжевой Книги.
О скольки из них ты слышал в каком-нибудь другом контексте?
А чо это за книга? Случаем не та самая, где Windows сертифицировано круче Linux и Solaris?
Насколько я знаю эта книга создается какой-то оборонной конторой США, не удивительно что первые места там занимают их собственные разработки, о которых мы не слышали. Где имена тех людей, которые проводили сертификацию? Где отчеты о тестах? О анализе кода? О анализе модели безопасности?
Всякая сертификация это не проверка на качество, а удовлетворение чьих-то амбиций, пополнение чьих-то карманов. За примером далеко идти не надо - UTM, сертифицированное ГСН РФ. Та же хуйня, только ГСН РФ меньше денег хочет чем аналог в США.

Marinavo_0507

> А чо это за книга?
Незнающий этого рассуждать о компьютерной безопасности не имеет права.
До отностительно недавнего времени существенно других критериев оценки безопасности просто не было.
> Насколько я знаю эта книга создается какой-то оборонной конторой США,
> не удивительно что первые места там занимают их собственные разработки, о которых мы не слышали.
Просил недоступное простым смертным? Просил. Получай.
Можно спорить, насколько грамотно была проведена сертификация, но факт, что при разработке учитывались некие критерии,
в отличие от любительских систем, где ограничиваются размахиванием руками с криками про obviously correct code.

sergey_m

но факт, что при разработке учитывались некие критерии, в отличие от любительских систем
Необоснованное ничем утверждение.

Marinavo_0507

Критерии, наряду с методологией тестирования, опубликованы.
Для любительских систем ничего подобного нет.

irinkina

>За примером далеко идти не надо - UTM, сертифицированное ГСН РФ. Та же хуйня, только ГСН РФ меньше денег хочет чем аналог в США.
Не нравится, не умеешь-не пользуйся.

sergey_m

> Критерии, наряду с методологией тестирования, опубликованы.
А где?

Marinavo_0507

http://csrc.ncsl.nist.gov/secpubs/rainbow/
вот здесь есть что-то, в том числе оранжевая книга
надо понимать, что кроме военных, это никому не надо особо - см. выше про законы рынка.
более новая несколько более практически применимая разработка --- common criteria, те самые, по которым windows 2000 сертифицировали
http://csrc.nist.gov/cc/index.html
если внимательно почитать, что показывает тот уровень, который получила windows,
там что-то вроде "иногда может работать, если рядом не дышать слишком громко"

sergey_m


http://csrc.ncsl.nist.gov/secpubs/rainbow/
вот здесь есть что-то, в том числе оранжевая книга
Ты её уже купил и прочитал? Думаю, нет. Поэтому пока не стоит говорить слово "факт".
если внимательно почитать, что показывает тот уровень, который получила windows,
там что-то вроде "иногда может работать, если рядом не дышать слишком громко"
Ну обосрать, не приведя ни одного теста, PoC и др. намного проще, чем создать продукт. А где же тот продукт, который супер-пупер? Только не надо отвечать, что мол его название есть в оранжевой книге. Нет возможности не только его увидеть, но даже купить. Поэтому его существование ничем не подтверждено.
Ей-богу, эти разговоры мне напонимают анекдот: "Повторяю, танк секретный, физики о нём не знают."

Marinavo_0507

> Ты её уже купил и прочитал? Думаю, нет.
Вообще-то, там тексты можно скачать, странно, что ты не заметил.
Оранжевую книгу я не читал, т.к. человек мирный, и меня детали не особо интересуют, ограничился обзором.
Читал Common Criteria.
> Ну обосрать, не приведя ни одного теста, PoC и др. намного проще, чем создать продукт.
Низкий уровень не означает, что оно обязательно сломается.
Он означает, что не было предствлено доказательств соответствия продукта более высоким требованиям.
> Нет возможности не только его увидеть, но даже купить.
У меня нет возможности увидеть миллион долларов, значит существование таких сумм ничем не подтверждено.
Уверен, что ни один из продуктов нельзя купить? Пробовал?
На самом деле, если почитаешь требования, то поймёшь, что платить за такое не будешь --- дорого обойдётся.

Marinavo_0507

http://www.geminisecure.com/
Там сказано, обращайтесь.
У них есть продукт, сертифицированный по классу A1.

Marinavo_0507

MLS LAN Secure Network Server System
Product Type: Network Security - Trusted Network Separation
Status: Evaluated
Assurance Level: TCSEC A1-MI
Manufacturer: Boeing Aerospace
Dealer: Boeing Aerospace
PO Box 3999
Seattle Washington 98124-2499
Phone: +1 206 773 0628
Facsimile: +1 206 773 1015
The MLS LAN Secure Network Server System (SNSS) is a network component which can support simultaneous transmission of digital data and analog video within a local area. SNSS comprises multiple Secure Network Servers (SNSs) connected by a transmission medium (e.g., Ethernet) and provides communications between attached devices (hosts, terminals etc.) operating at different sensitivity levels. Terminals are attached to an SNS terminal device interface card which performs user identification and authentication, access control and audit functions. A terminal user may connect to hosts on the network according to mandatory and discretionary access control. SNSS uses a distributed approach to network management.
Обращайся.

sergey_m

That means our platforms will be verifiably free of flaws and trap doors, and invulnerable to malicious software.
Они доказали, что в их программе нет глюков? Наверное стоит к ним обратиться по поводу доказательства, что бога нет.

sergey_m

> Ethernet
Так это же легко DoSимая среда. Как же так A1 сливает воду.

Marinavo_0507

> Они доказали, что в их программе нет глюков?
Почитай, что именно нужно доказывать для сертификации по классу A1.

sergey_m

Кроме того я сомневаюсь, что документ написанный 19 лет назад может описывать современные требования.

bleyman

2Глебиус: Дурак это не тот, кто совершил ошибку, а тот кто в ней упорствует.
Очень интересная манера вести спор: утверждать, что предмет спора (безопасный код) не существует, потому что не может существовать никогда. Прекрасно!
Если ты на самом деле не понимаешь, как можно доказывать безопасность кода, почитай сцылки. Хинт: за сертификат о безопасности надо заплатить туеву хучу бабок не просто так.

sergey_m

Очень интересная манера вести спор: утверждать, что предмет спора (безопасный код) не существует, потому что не может существовать никогда. Прекрасно!
А где я такое утверждал?

Dasar

> А где я такое утверждал?
Например, вот здесь:
Они доказали, что в их программе нет глюков? Наверное стоит к ним обратиться по поводу доказательства, что бога нет.
зы
Могу дать ВМиК-ашные номера аудиторий и часы занятий во время который рассказывают, что такое "доказательство правильности работы кода".

sergey_m

А есть ли материалы по этой теме в инете?

Ivan8209

В правила внеси.
---
...Я работаю антинаучным аферистом...

sergey_m

Там с самого начала Dimka сделал правило номер 7.

Ivan8209

Про переполнение --- это ты в точку.
Мне вообще нравится, когда сначала проверяют на нуль,
а потом усекают. Причём --- поразрядным "и."
---
...Я работаю антинаучным аферистом...

Marinavo_0507

> А есть ли материалы по этой теме в инете?
I will use Google before asking a dumb question?

sergey_m

Поэтому словосочетанию поисковики ничего путного не находят.

Marinavo_0507

Я перевёл ключевые слова на английский, и тут же нашёл несколько толковых ссылок.

Marinavo_0507

http://acmqueue.com/modules.php?name=Content&pa=showpage&pid=227
Интервью с разработчиком софта для марсохода частично поддерживает точку зрения Глеба.

mysha

Доказать правильность работы алгоритма - можно, но
правильность работы кода только в частных случаях, так как на
уровне абстракции языка C это потребует очень много ресурсов.
Ну и конечно в общем случае эта задача неразрешима.
Код можно проверить тестами (никто не застрахован от описок в коде...)
в общем случае построить полную систему тестов нельзя, однако
например для регулярных автоматов такая полная система есть.
Люди утверждают что большинство обычных программ эквивалентно автоматам с
конечным числом стеков, которые можно проверить на правильность работы (опять
же за экспоненциальную сложность).
И самый большой минус - для того чтобы доказать "правильность" работы
нужно составить спецификацию кода т.е. описать в чем же эта правильность заключается.
На данный момент для сложных программ сама программа и является этим описанием,
так как рассматривать все случаи - жизни не хватит.

buka

То есть должна быть какая-то объективная причина, принуждающая людей знающих что так делать нельзя, тем не менее писать плохой, подверженнный ошибкам код. В чем она состоит?

Меньше писать и быстрее работает Нафиг нужна программа, которая только и делает, что проверяет?

Ivan8209

То есть, прежде чем произвести выборку из строки,
надо обязательно убедиться, что ты в неё попадаешь,
и никак иначе?
---
...Я работаю антинаучным аферистом...

buka

А попонятней можно?

Ivan8209

Куда понятней?
Тебе всегда обязательно проверять, попадаешь ли ты в границы?
---
...Я работаю антинаучным аферистом...

buka

А, ты насчет "только и делает"...
Но тогда скорее уж запись.
Нет, мне -- вообще нихрена не обязательно

buka

Вопрос о расстановке проверок времени выполнения нетривиален.
Вот кто-нибудь скажет: проверяй лишь внешние данные, а что считать внешним? Такую защиту достаточно "проколоть".
"Любая проблема программирования решается введением дополнительной косвенности." Компонентность везде, модульность во всем... а как результат тьма не только прыжков, но и проверок на пути каждого второго вызова.
Доверие -- не только слабость в опасности, но и сила для дела!

sergey_m

Вот кто-нибудь скажет: проверяй лишь внешние данные, а что считать внешним? Такую защиту достаточно "проколоть".
Данные полученные ядром от процесса с uid 0 не внешние. Но их все равно нужно проверять, не устраивать же kernel panic из-за ошибки в приложении.

Ivan8209

Да, ты переоткрыл основной довод против микроядерных систем.
Отсюда вывод: надо проверять лишь те данные,
которые ввести _неумелый_ пользователь.
Для такого все внутренние прослойки должны быть недоступны,
а на ящике должна висеть табличка:


"Не влезай! Убьёт!"


А тем, кому нужна безопасность,
придётся поступиться скоростью и гибкостью.
---
...Я работаю антинаучным аферистом...

evgen5555

Безопасность нужна всем. Умелые пользователи тоже часто ошибаются, не так ли?

Ivan8209

Умелые пользователи, если ошибаются, винят в этом самих себя.
---
...Я работаю антинаучным аферистом...

bleyman

Умелые пользователи, если ошибаются, винят в этом самих себя.

Хуясе! Я как-то знаешь ли предпочитаю работать с таким софтом, после общения с которым никого не приходится ни в чем винить.

Ivan8209

Тогда не лезь в распределительный щиток, а вызывай электрика.
---
...Я работаю антинаучным аферистом...

buka

или _злонамеренный_
Спасибо, конечно, за признание моих достижений, но речь шла о компонентных системах и доверии вообще.
Соблазн опустить всякие-разные проверки есть всегда, вот и пишут "tricky" код.

bleyman

Тогда не лезь в распределительный щиток, а вызывай электрика.

Ты никогда не замечал, что распределительные щитки закрыты крышкой? А знаешь это для чего? А я вот тебе открою тайну: это для того чтобы даже охуенно умелый пользователь распределительных щитков не мог ткнуццо в оголенные провода _случайно_. И проходя мимо щитка ему бы не приходилось постоянно следить за тем, чтобы не тыкнуться. А, соответственно, если он уж решил залезть внутрь, у него есть возможность подготовиться, повысить внимательность и осторожность, запастись резиновыми перчатками (бэкапнуть систему) и таки открыть крышку, полностью осознавая что _после_ _этого_ его может йобнуть током.
По-моему, аналогия вполне ясна.

bleyman

Мы удалились от темы.
Отсюда вывод: надо проверять лишь те данные,
которые ввести _неумелый_ пользователь.
Для такого все внутренние прослойки должны быть недоступны,

Дай угадаю: ты в жизни не написал ни одной программы хоть сколько-нибудь системного уровня. То есть НЕ вебсайты на пхп и НЕ скрипты.
Я угадал?

mysha

Пожалуйста, приведи пример?
Сдается впечатление , что ты с софтом не работаешь, а иногда, запускаешь для прикола.
В результатах русской рулетки винить обычно нет кого, да и часто некому.

bleyman

Ну скажем винда не позволяет произвольной проге прописать МБР. Пример понятен?

Ivan8209

Нет.
---
...Я работаю антинаучным аферистом...

Ivan8209

"...Стоя босиком на стальном листе, случайно дотронулся кончиком
уха до оголённого провода, находящегося под напряжением в 12 кВ."
Какая существует разница между электриком, проходящим в костюме
мимо РЩ, и другим таким же человеком при таком же полном параде?
---
...Я работаю антинаучным аферистом...

bleyman

Понимаешь ли, если все время ходить в прорезиненном комбинезоне, то образуются пролежни.

bleyman

Нет.

Тогда что же послужило причиной появления у тебя в голове ощущения, что обработка ввода пользователя вообще стоит того чтобы оценивать потраченное на нее время? Это я про
Отсюда вывод: надо проверять лишь те данные,
которые ввести _неумелый_ пользователь.
Ну то есть я практически уверен, что эти слова абсолютно неуместны в разговоре про баланс между производительностью и безопасностью. По одной простой причине, которая очевидна любому, кто хоть раз писал программу сколько-нибудь системного уровня. То есть все что угодно кроме порносайта на пхп и каких-нить скриптов.

Ivan8209

В высокоуровневых средствах не помешает проверить разумность границ.
Хотя бы потому, что они видны всякому, в отличие от низкоуровневых,
которые уже расчитаны на умелого и ответственного пользователя.
---
...Я работаю антинаучным аферистом...

Dasar

Защита от дурака полезна на любом уровне.
В некотором смысле, многие парадигмы программирования/технологии как раз сделаны для того, чтобы добавить защиту от дурака даже на нижнем уровне.
Стандартные примеры:
1. Инкапсуляция - скрывается работа внутренних механизмов объекта/модуля/компонента для того, чтобы сложнее было "испортить" объект/модуль/компонент
2. Данные должны храниться в единичном экземпляра (например, это подтребования нормальных форм БД) - опять же чтобы уменьшить возникновения ситуации, когда программа находится в рассогласованном состоянии.
3. Вытесняющая многозадачность вместо кооперативной
4. Разграничение адресного пространства между процессами

mysha

Чем докажешь? Ты говоришь о произвольных прогах или
о произвольных прогах, известных тебе?
Ты думаешь сассер не сможет записать МБР если захочет?

bleyman

Мне неинтересно с тобой спорить, извини.

Ivan8209

Любая защита добавляет сложности и требует больше времени,
причём не только для исполнения.
Обычные ответы:
1а. "Microkernel is too slow." (Exokernel.)
1б. "...One consistent whole could well be megabytes in size
even though the individual components are not."
3. ОС РВ. (Согласующая многозадачность вместо вытесняющей.)
4. Высокоуровневые языки.
Положение "2" не относится непосредственно к защите.
---
...Я работаю антинаучным аферистом...

Dasar

> Любая защита добавляет сложности и требует больше времени
Дело в том, что хорошо спроектированная программа - автоматом обладает такой защитой.
Хорошая программа - это та, в которой - каждый участок кода занимается только своим делом.
> 3. ОС РВ. (Согласующая многозадачность вместо вытесняющей.)
неудачный пример, т.к. как раз в нынешних ОС РВ используется вытесняющая многозадачность.
Пример, тот же QNX.
Очевидно, что первым обязательным требованием к архитектуре ОС является многозадачность в истинном смысле этого слова. Варианты с псевдо-многозадачностью типа MS-Windows или Novell NetWare неприемлемы поскольку они допускают возможность блокировки или даже полного развала системы одним неправильно работающим процессом. Для предотвращения блокировок ОС должна использовать квантование времени (то есть принудительную а не добровольную многозадачность что является достаточно легкой задачей. Вторая проблема (надежность) может быть эффективно решена при полном использовании возможностей процессоров Intel 80386 и старше, что предполагает работу ОС в 32-х разрядном режиме процессора. Для эффективного обслуживания прерываний ОС должна использовать алгоритм диспетчеризации, обеспечивающий вытесняющее планирование, основанное на приоритетах. Кроме того, необходима эффектитвная поддержка сетевых коммуникаций, и взаимодействия между процессами, поскольку реальные технологические системы обычно управляются целым комплексом компьютеров и/или процессов. Весьма желательно также, чтобы ОС поддерживала множественные нити управления, а также симметричную мультипроцессорность.
> 4. Высокоуровневые языки.
Опять же в высокоуровневых языках - часто идет разделение "адресного" пространства уже даже не на уровне процесса, а на уровне компонент/модуль/объект.
И один компонент/модуль/объект не могут получить, напрямую никаким способом доступ к внутренностям другого компонента.
Пример: Java/C#, "честные" ООП, компонентные системы (Com/Corba мультиагентные системы.

Ivan8209

Существуют и внешние ограничения на возможности проектирования.
В частности, наличие хорошего оптимизирующего компилятора для
хорошего высокоуровневого языка принудит обойтись без разного
рода низкоуровневых хаков, а значит, предотвратит появление
соответствующих ошибок.
QNX --- плохая ОС РВ, требует много ресурсов.
Не самый лучший пример встроенной СРВ.
Есть факт: в наиболее требовательных (по временным или
пространственным ограничениям) местах по-прежнему применяют СРВ,
построенные на согласующей многозадачности.
Адресное пространство процесса и логическая организация памяти,
предоставляемая языком программирования --- это две очень
большие разницы.
---
...Я работаю антинаучным аферистом...

Dasar

> QNX --- плохая ОС РВ, требует много ресурсов.
> Не самый лучший пример встроенной СРВ
AFAIK, зато более надежная, т.к. по крайней мере есть гарантия на время обработки входных сигналов.
Согласующая - никаких гарантий не дает.
> Есть факт: в наиболее требовательных (по временным или
> пространственным ограничениям) местах по-прежнему применяют СРВ,
> построенные на согласующей многозадачности
Но все это же не от хорошей жизни, а только по причине нехватки ресурсов.
Причем все делается в ущерб надежности, т.е. нет никаких гарантий, что, например, из-за ошибки в драйвере принтера не ляжет вся система.
> Адресное пространство процесса и логическая организация памяти,
> предоставляемая языком программирования --- это две очень
> большие разницы.
если брать такие системы, как Java или .Net - имеющих "песочницу" для работы с памятью, то никакой разницы между адресным пространством и логической организацией нет.
И в том, и в другом случае мы не можем получить доступ к чужой памяти,
и в том, и в другом случае из-за ошибок в проверках можно получить доступ к чужой памяти.
Опять же "песочница" Java-ы или .Net-а может быть выполнена на hardware-ном уровне.
Поэтому не вижу ни каких оснований считать - это двумя очень большими разницами.

Ivan8209

А почему она должна быть более надёжной.
Только потому, что, вообще говоря, позволяет свободно
разгуливать по всей доступной памяти?
Но ведь никто никого не обязывает писать в произвольные,
случайным образом определяемые ячейки памяти случайные числа.
Отказ в ПО управления принтером --- это не из области СРВ.
Не подменяй.
Если ты смешиваешь аппаратную и программную виртуальные машины,
то что тебе мешает столь же свободно переходить от аппаратной
виртуальной машины к проектируемой виртуальной машине,
существующей в голове программиста?
Только потому, что так не принято в широкораспространённых учебниках?
---
...Я работаю антинаучным аферистом...

Dasar

> А почему она должна быть более надёжной.
Потому что гарантируется время отклика
> Только потому, что, вообще говоря, позволяет свободно
разгуливать по всей доступной памяти?
в qnx-е память общая разве?
> Отказ в ПО управления принтером --- это не из области СРВ.
Почему это?
Есть СРВ, которая управляет, например, АЭС.
Есть правило, что всякое управление должно оставлять бумажный след.
Соответственно в СРВ, кроме управлениия АЭС-ом будет и выдача на печать.
Соответственно, если драйвер принтера (задача печати) зависнет (задумается то в случае коорпоративной многозадачности умрет и обработка управления.
Соответственно мы получили, что при ошибках в менее важных задачах (выдача на принтер) дохнет вся система
И где в данном случае, какая-то польза от корпоративной многозадачности?
вытесняющая многозадачность - даже в данном случае, позволить обрабатывать управление.
> проектируемой виртуальной машине, существующей в голове программиста?
Если эта ВМ явно реализована (в коде, в железе, в виде бизнесс-процесса) - то да, такую ВМ тоже можно принимать во внимание.

Ivan8209

Какое непосредственное влияние средства защиты оказывают
на время отклика?
Если отказ (опоздание) в управлении устройством не приводит
к ошибке, то это не является заданием реального времени.
Соответственно, и система сама --- уже гибридная.
Есть повседневный опыт, который говорит о том, что СРВ,
основанные на вытесняющей многозадачности, требуют значительно
больших ресурсов и обладают большим временем отклика, чем
соответствующие СРВ с согласующей многозадачностью.
ВМ, кстати, легко может быть реализована в виде СРВ
без защиты памяти и без прочих лишних наворотов.
---
...Я работаю антинаучным аферистом...

Dasar

> Какое непосредственное влияние средства защиты оказывают на время отклика?
Тем что гарантируется, что каждая задача получит управление в заданные периоды времени.
Или что с момента получения сигнала до его обработки пройдет меньше заданного времени.
> Если отказ (опоздание) в управлении устройством не приводит
> к ошибке, то это не является заданием реального времени.
устройства к СРВ подключаются разные с разными режимами работы, и разным необходимым временем отклика
в данном случае, есть, например, две задачи:
выполнение печати с временем отклика - 30 минут
управление насосом охлаждения с периодом отклика - 50 мс
Соответственно, СРВ с корпоративной многозадачностью не гарантируют, что управление насосом будет работать, если задача управления принтером почему-то задумается.
> Есть повседневный опыт, который говорит о том, что СРВ,
> основанные на вытесняющей многозадачности, требуют значительно
> больших ресурсов и обладают большим временем отклика, чем
> соответствующие СРВ с согласующей многозадачностью
Задача увеличения ресурсов - всегда проще и дешевле, чем задача получения дополнительно качества.
На вытесняющей многозадачности - ставим процессор в два раза быстрее - и получаем такую же скорость, как у вытесняющей.
Наоборот - не верно, как не меняй СРВ корпоративную многозадачность, все равно гараний отклика не получишь.
> ВМ, кстати, легко может быть реализована в виде СРВ
> без защиты памяти и без прочих лишних наворотов
Внешние задачи как получают доступ к этой ВМ?

Ivan8209

А в согласующей многозадачности такое не гарантируется?
У тебя машинные такты случайным образом изменяются от наносекунд
до минут?
Я понял, в чём затык с принтером.
Тебе не кажется, что ошибок не должно быть вообще?
Или как ты собираешься заменять встроенную систему?
Задача увеличения ресурсов далеко не всегда проще и очень часто
заметно дороже. У тебя неверные данные.
Процессор вдвое большей мощности потребует, по меньшей мере,
вдвое больше питания, будет выделять больше тепла и так далее.
К ВМ все внешние задачи получают доступ независимо от того,
как эта ВМ сделана, аппаратно или программно-аппаратно,
и от того, какие алгоритмы использовались программистами.
---
...Я работаю антинаучным аферистом...

Dasar

> Тебе не кажется, что ошибок не должно быть вообще?
Это нереализуемая утопия.
Реальнее говорить - о количестве ошибок на строчку кода.
С этой точки зрения у задачи управления насосом кол-во ошибок на строчку кода на порядок или на два меньше,
чем в задаче управления принтером.
> Или как ты собираешься заменять встроенную систему?
перепрограммировать ПЗУ
перешить флешку
> Задача увеличения ресурсов далеко не всегда проще и очень часто
> заметно дороже. У тебя неверные данные.
> Процессор вдвое большей мощности потребует, по меньшей мере,
> вдвое больше питания, будет выделять больше тепла и так далее.
Речь идет о тиражных внедрениях, или единичных - мелкосерийных внедрениях?
> К ВМ все внешние задачи получают доступ независимо от того,
> как эта ВМ сделана, аппаратно или программно-аппаратно,
> и от того, какие алгоритмы использовались программистами.
В данном случае важно - могут или не могут внешние задачи обходить тот интерфейс, который им навязывает ВМ. Если интерфейс ВМ обходится - то это уже не ВМ.

Ivan8209

> Это нереализуемая утопия.
Кто тебе об этом сказал?
Есть, например, такие отцы, обучавшиеся ещё в незапамятные
времена у Джона Маккарти, которые утверждают иное.
> перепрограммировать ПЗУ
> перешить флешку
На лету?
> Речь идёт о тиражных внедрениях или единичных - мелкосерийных
> внедрениях?
Ты считаешь, что определяющим показателем является стоимость
набора микросхем? У них есть ещё и другие объективные различия.
А как ты думаешь, сможешь ли ты напрямую изменить данные,
уже находящиеся в памяти встроенной КИС?
Или ещё чего-нибудь такого же встроенного.
---
...Я работаю антинаучным аферистом...

Dasar

> Кто тебе об этом сказал?
Пользователи - которые не готовы платить таких денег.
> На лету?
> А как ты думаешь, сможешь ли ты напрямую изменить данные,
уже находящиеся в памяти встроенной КИС?
Да, смогу и на лету, не останавливая эксплутации.
Такие системы делаются с двойным или тройным резервированием.
Соответственно можно останавливать блоки по одному, и менять на них прошивку.
> Ты считаешь, что определяющим показателем является стоимость
> набора микросхем? У них есть ещё и другие объективные различия.
Стоимость тоже показать - но в меньшей степени.
В большей степени, играют разные подходы.
Если система массово-тиражируемая, то поддержка будет осуществляться силами пользователя.
Если система одиночная - мелкосерийная, то она обслуживание делается силами разработчика.
И фактически - первая схема диктует монологовую схему работы (с длинными итерациями, и слабой обратной связью вторая схема - диалоговая - мы имеем быстрые итерации с сильной обратной связью.

mysha

Есть, например, такие отцы, обучавшиеся ещё в незапамятные
времена у Джона Маккарти, которые утверждают иное.

Ссылку на отцов пожалуйста (работу, или хотя-бы ФИО).
или автор поста так скромно на себя ссылается?
В незапамятные времена и коммунизм в 2000 году обещали

bleyman

Но ведь никто никого не обязывает писать в произвольные,
случайным образом определяемые ячейки памяти случайные числа.

У меня создается стойкое ощущение, что КОНТРА - чистый теоретик программирования. Типа как тетеньки которые на ВМК рассказывают про разные Паскали с Модулами и другие Алгоритмические Языки.
Однажды писал мой папа прогу для микропроцессора, который ставился в охранный передатчик. И, соответственно, прога должна работать без глюков год подряд, например. Ну или по крайней мере глючить незаметно.
А она, сцука, вдруг начала глючить. Ну ладно, там типа антенна рядом, мб она процессору москиппет, по поводу чего все внутренние структуры срочно обкладываются контрольными суммами, хранятся в трех экземплярах, ошибки автоматически исправляются, все зашибись. Глюки почти исчезают.
Да, кстати, заметь - прога одна, о многозадачности никто не говорит. Ну то есть она, конечно, много вещей делает, но это все достаточно вменяемо синхронизированно.
Да, кстати, очень поучительно писать прогу, точно зная, что даже если у меня случайно обнулится случайный байт в оперативке, ничего особо страшного произойти не должно - в крайнем случае ребут с зачитыванием состояния с внешней памяти. Очень, очень поучительно. После такого икспериенса на людей, говорящих
Но ведь никто никого не обязывает писать в произвольные,
случайным образом определяемые ячейки памяти случайные числа.

смотришь как на конченных долбоебов, типа тех тётенек с АЯ... Че-то я повторяюсь.
Ну так вот. Через два года (два! года!) обнаружилось что в коде на асме обнуляющем буфер для какой-то херни вместо MOV (по внутренней памяти) стояло MOVX (то есть по внешней). Соответственно, поскольку MOVX в качестве адреса использует совершенно левые регистры, то нолики прописывались в совершенно случайное место внешней памяти. А буфер все равно потом перезаписывался, так что было совершенно незаметно что что-то не так.
Место было вполне критическим - что-то там в прерывании откуда-то считывалось, поэтому асм был оправдан.
Это я к тому, что ситуации с прописыванием ноликов в память РЕАЛЬНЫ, причем в практически любой ситуации. В _реальной_ _жизни_ а не в книжках "Теория Программирования На Фортране" они случаются, и довольно часто, и к ним надо быть готовым. Поэтому С#, в котором прописать куда-нибудь нолик достаточно сложно (но можно, я проверял - добро, а С/С++ - зло, когда надо не Hello World наваять, а что-нибудь БОЛЬШОЕ. Причем быстро.
Особенно хорошо я это понял, когда немножко убил цпповый хип (за границу массива немножко вылез причем глюк всплыл, естественно, через две недели и в совершенно другом месте. То есть вначале даже непонятно было в чем фишка - просто ДиректХ мне _иногда_ говорил, что какой-то д3д объект не освобожден. Причем под дебаггером глюк исчезал.
И я до сих пор считаю, что мне очень повезло, что в процессе вырезания кусков кода глюк не мутировал, а продолжал проявляться, так что я нашел его всего за пять часов.
Все вышесказанное относится к заявлению
Но ведь никто никого не обязывает писать в произвольные,
случайным образом определяемые ячейки памяти случайные числа.

garikus

respect

sergey_m

КОНТРА - чистый теоретик программирования
Он безнадежный перфекционист. Что вообще многим практикам не помешало бы.

Ivan8209

> Однажды писал
Лишнюю болтовню пропускаем и внимательно читаем следующее:
> для какой-то херни вместо MOV (по внутренней памяти)
> стояло MOVX (то есть по внешней).
То есть, в программе была сделана ошибка.
> Это я к тому, что ситуации с прописыванием ноликов в память
> РЕАЛЬНЫ, причем в практически любой ситуации.
Осталось уточнить: ситуации, когда сделана ошибка.
---
...Я работаю антинаучным аферистом...
Оставить комментарий
Имя или ник:
Комментарий: