# V755. Copying from potentially tainted data source. Buffer overflow is possible.

- Небезопасная работа с аргументами командной строки
- Небезопасная работа с потоками ввода
- Небезопасное возвращаемое значение
- Исключения

Анализатор обнаружил, что в буфер копируются данные из небезопасного источника.

Примерами таких источников являются:

- аргументы командной строки, длина которых неизвестна;
- потоки ввода стандартной библиотеки в сочетании с С-строками (нуль-терминированными строками);
- возвращаемое значение небезопасных функций.

## Небезопасная работа с аргументами командной строки

Пример небезопасной работы с аргументами командной строки:

    int main(int argc, char *argv[])
    {
      ....
      const size_t buf_size = 1024;
      char *tmp = (char *) malloc(buf_size);
      ....
      strcpy(tmp, argv[0]);
      ....
    }

В случае, когда размер копируемых данных превысит размер буфера, произойдёт его переполнение. Для того чтобы избежать этого, лучше вычислить требуемый объём памяти заранее:

    int main(int argc, char *argv[])
    {
      ....
      char buffer[1024];
      errno_t err = strncpy_s(buffer, sizeof(buffer), argv[0], 1024);
      ....
    }

Также можно выделять память по мере необходимости, используя функцию 'realloc'. В C++ для работы со строками можно использовать классы, такие как 'std::string'.

## Небезопасная работа с потоками ввода

До стандарта С++20 была доступна возможность использовать C-строку в качестве буфера-приёмника для стандартных потоков ввода ('std::cin', 'std::ifstream'):

    void BadRead(char *receiver)
    {
      std::cin >> receiver;
    }

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

    void Exception2Cpp20()
    {
      char *buffer1 = new char[10];
      std::cin >> buffer1;          // Won't compile since C++20

      char buffer2[10];
      std::cin >> buffer2;          // no overflow
                                    // max 9 chars will be read
    }

Более подробно это изменение (с примерами и применением) освещено в предложении P0487R1 к стандарту С++ 20.

## Небезопасное возвращаемое значение

Злоумышленники могут манипулировать значением, возвращаемым некоторыми функциями, поэтому следует быть предельно аккуратными при работе с ними:

    void InsecureDataProcessing()
    {
      char oldLocale[50];
      strcpy(oldLocale, setlocale(LC_ALL, nullptr));
      ....
    }

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

## Исключения

Предупреждение не выдаётся в случаях, если источник данных неизвестен:

    void Exception1(int argc, char *argv[])
    {
      char *src = GetData();
      char *tmp = (char *)malloc(1024);
      strcpy(tmp, src);
      ....
    }

Выявляемые диагностикой ошибки классифицируются согласно ГОСТ Р 71207–2024 как критические и относятся к типу: Ошибки непроверенного использования чувствительных данных (ввода пользователя, файлов, сети и пр.).

Данная диагностика классифицируется как:

CWE-123 CERT-STR31-C