Дэвид Лебланк - 19 смертных грехов, угрожающих безопасности программ

Тут можно читать онлайн Дэвид Лебланк - 19 смертных грехов, угрожающих безопасности программ - бесплатно ознакомительный отрывок. Жанр: comp-programming. Здесь Вы можете читать ознакомительный отрывок из книги онлайн без регистрации и SMS на сайте лучшей интернет библиотеки ЛибКинг или прочесть краткое содержание (суть), предисловие и аннотацию. Так же сможете купить и скачать торрент в электронном формате fb2, найти и слушать аудиокнигу на русском языке или узнать сколько частей в серии и всего страниц в публикации. Читателям доступно смотреть обложку, картинки, описание и отзывы (комментарии) о произведении.
  • Название:
    19 смертных грехов, угрожающих безопасности программ
  • Автор:
  • Жанр:
  • Издательство:
    неизвестно
  • Год:
    неизвестен
  • ISBN:
    нет данных
  • Рейтинг:
    3.6/5. Голосов: 101
  • Избранное:
    Добавить в избранное
  • Отзывы:
  • Ваша оценка:
    • 80
    • 1
    • 2
    • 3
    • 4
    • 5

Дэвид Лебланк - 19 смертных грехов, угрожающих безопасности программ краткое содержание

19 смертных грехов, угрожающих безопасности программ - описание и краткое содержание, автор Дэвид Лебланк, читайте бесплатно онлайн на сайте электронной библиотеки LibKing.Ru

Эта книга необходима всем разработчикам программного обеспечения, независимо от платформы, языка или вида приложений. В ней рассмотрены 19 грехов, угрожающих безопасности программ, и показано, как от них избавиться. Рассмотрены уязвимости на языках C/C++, C#, Java, Visual Basic, Visual Basic.NET, Perl, Python в операционных системах Windows, Unix, Linux, Mac OS, Novell Netware. Авторы издания, Майкл Ховард и Дэвид Лебланк, обучают программистов, как писать безопасный код в компании Microsoft. На различных примерах продемонстрированы как сами ошибки, так и способы их исправления и защиты от них. Если вы программист, то вам просто необходимо прочесть эту книгу.

Перевод: А. Слинкин

19 смертных грехов, угрожающих безопасности программ - читать онлайн бесплатно ознакомительный отрывок

19 смертных грехов, угрожающих безопасности программ - читать книгу онлайн бесплатно (ознакомительный отрывок), автор Дэвид Лебланк
Тёмная тема
Сбросить

Интервал:

Закладка:

Сделать

Целое без знака в более широкое целое без знака.Это простейший случай: новое число дополняется нулями, чего вы обычно и ожидаете. Следовательно, (unsigned char)0xff после приведения к типу unsigned long становится равно

0x000000ff.

Целое без знака в целое со знаком того же размера.Так же как при приведении целого со знаком к целому без знака, комбинация битов сохраняется, а значение может измениться в зависимости от того, был ли старший (знаковый) бит равен 1 или 0.

Целое без знака в более широкое целое со знаком.Так же как при приведении целого без знака к более широкому целому без знака, значение сначала дополняется нулями до нужного беззнакового типа, а затем приводится к знаковому типу. Значение не изменяется, так что никаких сюрпризов в этом случае не бывает.

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

Преобразования при вызове операторов

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

...

template

void WhatIsIt(T value)

{

if((T)-1 < 0)

printf("Со знаком");

else

printf("Без знака");

printf(" – %d бит\n", sizeof(T)*8);

}

Для простоты оставим в стороне случай смешанных операций над целыми и числами с плавающей точкой. Правила формулируются так:

□ если хотя бы один операнд имеет тип unsigned long, то оба операнда приводятся к типу unsigned long. Строго говоря, long и int – это два разных типа, но на современных машинах тот и другой имеют длину 32 бита, поэтому компилятор считает их эквивалентными;

□ во всех остальных случаях, когда длина операнда составляет 32 бита или меньше, операнды расширяются до типа int, и результатом является значение типа int.

Как правило, ничего неожиданного при этом не происходит, и неявное приведение в результате применения операторов может даже помочь избежать некоторых переполнений. Но бывают и сюрпризы. Во–первых, в системах, где имеется тип 64–разрядного целого, было бы логично ожидать, что коль скоро unsigned short и signed short приводятся к int, а операторное приведение не нарушает корректность результата (по крайней мере, если вы потом не выполняете понижающего приведения до 16 битов), то unsigned int и signed int будут приводиться к 64–разрядному типу (_int64). Если вы думаете, что все так и работает, то вынуждены вас разочаровать – по крайней мере, до той поры, когда стандарт C/C++ не станет трактовать 64–разрядные целые так же, как остальные.

Вторая неожиданность заключается в том, что поведение изменяется еще и в зависимости от оператора. Все арифметические операторы (+, – ,*,/,%) подчиняются приведенным выше правилам. Но им же подчиняются и поразрядные бинарные операторы (&,|,А); поэтому (unsigned short) | (unsigned short) дает int! Те же правила в языке С распространяются на булевские операторы (&&,|| и !), тогда как в С++ возвращается значение встроенного типа bool. Дополнительную путаницу вносит тот факт, что одни унарные операторы модифицируют тип, а другие–нет. Оператор дополнения до единицы (~) изменяет тип результата, поэтому -((unsigned short)0) дает int, тогда как операторы префиксного и постфиксного инкремента и декремента (++, – ) типа не меняют.

Один программист с многолетним стажем работы предложил следующий код для проверки того, возникнет ли переполнение при сложении двух 16–разрядных целых без знака:

...

bool IsValidAddition(unsigned short x, unsigned short y)

{

if(x + y < x)

return false;

return true;

}

Вроде бы должно работать. Если результат сложения двух положительных чисел оказывается меньше какого–то слагаемого, очевидно, что–то не в порядке. Точно такой же код должен работать и для чисел типа unsigned long. Увы, программист не учел, что компилятор оптимизирует всю функцию так, что она будет возвращать true.

Вспомним из предыдущего обсуждения, какой тип имеет результат операции unsigned short + unsigned short. Это int. Каковы бы ни были значения целых без знака, результат никогда не может переполнить тип int, поэтому сложение всегда выполняется корректно. Далее int сравнивается с unsigned short. Значение х приводится к типу int и, стало быть, никогда не будет больше х + у. Чтобы исправить код, нужно лишь привести результат обратно к unsigned short:

...

if((unsigned short)(x + y) < x)

Этот код был показан хакеру, специализирующемуся на поиске ошибок, связанных с переполнением целых, и он тоже не заметил ошибки, так что наш опытный программист не одинок!

Арифметические операции

Не упускайте из виду последствия приведений типов и применения операторов, размышляя над корректностью той или иной строки кода, – в результате неявных приведений может возникнуть переполнение. Вообще говоря, нужно рассмотреть четыре основных случая: операции только над знаковыми типами, только над беззнаковыми типами и смешанные операции. Проще всего операции над беззнаковыми типами одного размера, затем идут операции над знаковыми типами, а когда встречаются смешанные операции, нужно принять во внимание правила приведения. В следующих разделах мы обсудим возможные ошибки и способы их исправления для каждого случая.

Сложение и вычитание.Очевидная проблема при выполнении этих операций – возможность перехода через верхнюю и нижнюю границы объявленного типа. Например, если речь идет о 8–разрядных числах без знака, то 255 + 1 = 0. Или: 2 – 3 = 255. В случае 8–разрядных чисел со знаком 127 + 1 = -128. Менее очевидная ошибка возникает, когда числа со знаком используются для представления размеров. Если кто–то подсунет вам число–20, вы прибавите его к 50, получите 30, выделите буфер длиной 30 байтов, а затем попытаетесь скопировать в него 50 байтов. Все, вы стали жертвой хакера. Помните, особенно при программировании на языке, где переполнить целое трудно или невозможно, – что вычитание из положительного числа, в результате которого получается число, меньшее исходного, – это допустимая операция, и никакого исключения вследствие переполнения не будет, но поток исполнения программы может отличаться от ожидаемого. Если вы предварительно не проверили, что входные данные попадают в положенный диапазон, и не уверены на сто процентов, что переполнение невозможно, контролируйте каждую операцию.

Умножение, деление и вычисление остатка.Умножение чисел без знака не вызывает трудностей: любая операция, где а * b > MAX_INT, дает некорректный результат. Правильный, но не очень эффективный способ контроля заключается в том, чтобы проверить, что b > MAX_INT/a. Эффективнее сохранить результат в следующем по ширине целочисленном типе (если такой существует) и посмотреть, не возникло ли переполнение. Для небольших целых чисел это сделает за вас компилятор. Напомним, что short * short дает int. При умножении чисел со знаком нужно еще проверить, не оказался ли результат отрицательным вследствие переполнения.

Читать дальше
Тёмная тема
Сбросить

Интервал:

Закладка:

Сделать


Дэвид Лебланк читать все книги автора по порядку

Дэвид Лебланк - все книги автора в одном месте читать по порядку полные версии на сайте онлайн библиотеки LibKing.




19 смертных грехов, угрожающих безопасности программ отзывы


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


Понравилась книга? Поделитесь впечатлениями - оставьте Ваш отзыв или расскажите друзьям

Напишите свой комментарий
x