CERT C: Rule POS39-C

Используйте правильный порядок байтов при передаче данных между системами

Описание

Определение правила

Используйте правильный порядок байтов при передаче данных между системами.[1]

Реализация Polyspace

Эта проверка проверяет переупорядочивание отсутствующих байтов при переносе данных.

Примеры

расширить все

Проблема

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

  • Перед отправкой данных в сетевой сокет.

  • После получения данных от сетевого сокета.

Риск

Некоторые системные архитектуры реализуют маленькое эндовое упорядоченное расположение байтов (сначала наименее значительный байт), а другие системы реализуют большое эндовое (сначала самый значительный байт). Если конечность отправленных данных не совпадает с конечностью принимающей системы, значение, возвращаемое при считывании данных, является неправильным.

Зафиксировать

После получения данных от сокета используйте функцию упорядоченного расположения байтов, такую как ntohl(). Перед отправкой данных в сокет используйте функцию упорядоченного расположения байтов, такую как htonl() .

Пример - Данные, переданные без переупорядочивания байтов
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <byteswap.h>
#include <unistd.h>
#include <string.h>


unsigned int func(int sock, int server)
{
    unsigned int num;   /* assume int is 32-bits */
    if (server)
    {
        /* Server side */
        num = 0x17;
		/* Endianness of server host may not match endianness of network. */
        if (send(sock, (void *)&num, sizeof(num), 0) < (int)sizeof(num)) 
        {
            /* Handle error */
        }
        return 0;
    }
    else {
        /* Endianness of client host may not match endianness of network. */
        if (recv (sock, (void *)&num, sizeof(num), 0) < (int) sizeof(num))  
        {
            /* Handle error */
        }
		
		/* Comparison may be inaccurate */
        if (num> 255)  
        {
            return 255;
        }
        else
        {
            return num;
        }
    }
}
        
      

В этом примере переменные num присвоено шестнадцатеричное значение 0x17 и отправляется по сети клиенту с сервера. Если хост сервера является маленьким эндовым, а сеть является большой эндовой, num передается как 0x17000000. Затем клиент считывает неправильное значение для num и сравнивает его с локальным числовым значением.

Коррекция - используйте функцию упорядоченного расположения байтов

Перед отправкой num с хоста сервера используйте htonl() для преобразования из хоста в упорядоченное расположение сетевых байтов. Точно так же перед чтением num на клиентском узле используйте ntohl() для преобразования из сети в упорядоченное расположение хоста.

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <byteswap.h>
#include <unistd.h>
#include <string.h>

unsigned int func(int sock, int server)
{
    unsigned int num;   /* assume int is 32-bits */
    if (server)
    {
        /* Server side */
        num = 0x17;
		
		/* Convert to network byte order. */
        num = htonl(num); 
        if (send(sock, (void *)&num, sizeof(num), 0) < (int)sizeof(num)) 
        {
            /* Handle error */
        }
        return 0;
    }
    else {
        if (recv (sock, (void *)&num, sizeof(num), 0) < (int) sizeof(num)) 
        {
            /* Handle error */
        }
		
		/* Convert to host byte order. */
        num = ntohl(num); 
        if (num > 255) 
        {
            return 255;
        }
        else
        {
            return num;
        }
    }
} 

Проверяйте информацию

Группа: Правило 50. POSIX (POS)
Введенный в R2019a

[1] Это программное обеспечение было создано MathWorks, включающее фрагменты: «Сайт SEI CERT-C», © 2017 Университет Карнеги Меллон, Веб-сайт SEI CERT-C + + © 2017 Университет Карнеги Меллон, "Стандарт кодирования SEI CERT C - Правила разработки безопасных, Надежные и безопасные системы - 2016 Edition ", © 2016 Университет Карнеги Меллон, и "Стандарт кодирования SEI CERT C++ - Правила разработки безопасных, Надежные и безопасные системы в C++ - 2016 Edition "© 2016 Университет Карнеги Меллон, с специального разрешения от его Института программной инженерии.

ЛЮБОЙ МАТЕРИАЛ УНИВЕРСИТЕТА КАРНЕГИ МЕЛЛОН И/ИЛИ ЕГО ИНЖЕНЕРНОГО ИНСТИТУТА ПРОГРАММНОГО ОБЕСПЕЧЕНИЯ, СОДЕРЖАЩИЙСЯ В НАСТОЯЩЕМ ДОКУМЕНТЕ, ПОСТАВЛЯЕТСЯ НА БАЗИСЕ «КАК ЕСТЬ». УНИВЕРСИТЕТ КАРНЕГИ МЕЛЛОН НЕ ДАЕТ НИКАКИХ ГАРАНТИЙ, ВЫРАЖЕННЫХ ИЛИ ПОДРАЗУМЕВАЕМЫХ, В ОТНОШЕНИИ ЛЮБОГО ВОПРОСА, ВКЛЮЧАЯ, НО НЕ ОГРАНИЧИВАЯСЬ, ГАРАНТИЮ ПРИГОДНОСТИ ДЛЯ ЦЕЛЕЙ ИЛИ КОММЕРЧЕСКОЙ ВЫГОДЫ, ИСКЛЮЧИТЕЛЬНОСТИ, ИЛИ УНИВЕРСИТЕТ КАРНЕГИ МЕЛЛОН НЕ ДАЕТ НИКАКИХ ГАРАНТИЙ В ОТНОШЕНИИ СВОБОДЫ ОТ ПАТЕНТА, ТОВАРНОГО ЗНАКА ИЛИ НАРУШЕНИЯ АВТОРСКИХ ПРАВ.

Это программное обеспечение и связанная с ним документация не были рассмотрены и не одобрены Университетом Карнеги-Меллон или его Институтом программной инженерии.