Небольшая задачка: Найди "дырку"

Тема в разделе "Флудилка", создана пользователем NR55RU, 23 сен 2014.

  1. NR55RU

    NR55RU Гик

    Тут в процессе прочтения, весьма интересной книги "24 греха компьютерной безопасности" наткнулся на один весьма любопытный и очень не очевидный пример "дырки" которая может приводить к переполнению буфера.

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

    Вот код:
    Код (Text):
    #define MAX_BUF 256
    void someFunction( char* input )
    {
        short len;
        char buf[ MAX_BUF ];
       
        len = strlen( input );
       
        if ( len < MAX_BUFF )
        {
            strcpy( buf, input );
        }
    }
    Попробуйте разобраться в том в каких случаях этот код станет не безопасным и приведет к переполнению массива в переменной buf.
    Вроде все верно, указан максимальный размер, проверяется длинна и производится сравнение ... но нет.. тут есть "дырка" :)
    Весьма любопытный пример надо сказать :)

    Через сутки я напишу тут подробный ответ, а пока не стоит писать ответы и спойлерить если вы догадались, дайте другим поломать голову :)
     
  2. Unixon

    Unixon Оракул Модератор

    Решето! :D
     
  3. NR55RU

    NR55RU Гик

    И так в чем была проблема.
    Давайте для простоты представим что тип short равен 1 байту а int равен 2 байтам, так будет проще понять.
    Предположим что мы передали в функцию строку длинною 511 байт.
    Функция stlen() имеет возвращаемый тип size_t что как правило соответствует некоему целочисленному значению без знака, размер обычно варьируется от системы к системе и может иметь и 32 и 64 разряда.

    Предположим что в нашем случае size_t является unigned int и соответствует 2 байтам.
    Таким образом функция вернет нам значение 511 что в двоичном виде будет выглядеть так:
    1 байт [00000001] 2 байт [11111111]
    Но принимающей переменной у нас является переменная short размер которой составляет всего 1 байт, следовательно возвращаемое значение слишком велико и оно будет усечено, просто 1 байт будет выкинут и в переменную len будет записан 2 байт.
    Но наша переменная является знаковой а как известно старший значащий бит в знакомых числах интерпретируется как наличие или отсутствие знака, в итоге в нашей переменой len окажется ничто иное как отрицательное значение -127

    Объявленное в define число будет интерпретироваться как signed int, то есть число со знаком и при операции сравнения, наше переменная len будет повышена до signed int с сохранением знака.
    В итоге len будет всегда меньше 256 и условие будет выполняться.

    Ну а так как функция strcpy определяет конец строки по нулевому байту, она послушно скопирует 511 байт, выйдя далеко за границы отведенной для буфера памяти.

    Вот собственно и все :) Как сказал Unixon - РЕШЕТО :)

    Ну а кто не в курсе чем опасны дырки с переполнением буфера, почитайте инет, очень удивитесь :)

    P.s. Вообще функции типа srtcpy и её давании собраться, давно помечены как не безопасные, а при их использовании современные компиляторы выдают предупреждения, а им на смену пришли доработанные и более безопасные варианты :)
     
  4. Unixon

    Unixon Оракул Модератор

    Это еще не всё :)
    Что сделает strcpy, если фактическая длина строки окажется больше, чем можно записать в size_t ?
    На всякий случай стоит заменить strcpy на strncpy, там хотя бы размер буфера можно указать.
     
  5. NR55RU

    NR55RU Гик

    Вероятнее всего речь идет о strlen ?, strcpy как я понимаю вообще длину никак не отслеживает.
    А strlen теоретически при превышении размера size_t, переменная обнулится (и не раз если передать строку длинною size_t x2 или х3 или х4 и тд) и строка длиною в много миллионов символов может оказаться всего в 1 символ например, проверка это дело пропустит а strcpy все это многомиллионное добро попытается записать :)
    По сути получается проблема целочисленного переполнения.
    Так ?:)
     
  6. Unixon

    Unixon Оракул Модератор

    Теоретически, да. Интересно, обрабатываются ли эти случаи в библиотеке?