exponenta event banner

CERT C: POS38-C правил

Остерегайтесь расовых условий при использовании дескрипторов вилки и файлов

Описание

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

Остерегайтесь расовых условий при использовании дескрипторов вилки и файлов. [1 ]

Внедрение Polyspace

Эта проверка проверяет подверженность дескриптора файла дочернему процессу.

Примеры

развернуть все

Проблема

Воздействие дочернего процесса на дескриптор файла происходит, когда процесс раскачивается, а дочерний процесс использует дескрипторы файлов, унаследованные от родительского процесса.

Риск

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

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

Убедитесь, что файл не был изменен перед форсировкой процесса. Закройте все унаследованные дескрипторы файлов и снова откройте их с более строгими разрешениями и привилегиями, такими как разрешение только для чтения.

Пример - Доступ к дескриптору файла из Forked Process
# include <stdio.h>
# include <stdlib.h>
# include <string.h>
# include <unistd.h>
# include <fcntl.h>
# include <sys/types.h>
# include <sys/stat.h>



const char *test_file="/home/user/test.txt";

void func(void)
{
    char c;
    pid_t pid;
	/* create file descriptor in read and write mode */
    int fd = open(test_file, O_RDWR); 
    if (fd == -1)
    {
        /* Handle error */
		abort();
    }
	/* fork process */
    pid = fork();
    if (pid == -1)
    {
        /* Handle error */
		abort();
    }
    else if (pid == 0)
    {   /* Child process accesses file descriptor inherited 
		from parent process */
        (void)read(fd, &c, 1);
	}
    else
    {   /* Parent process access same file descriptor as 
		child process */
        (void)read(fd, &c, 1);
    }
}
      

В этом примере дескриптор файла fd создается в режиме чтения и записи. Затем процесс раскручивают. Дочерний процесс наследует и получает доступ fd с теми же разрешениями, что и родительский процесс. Существует условие гонки между родительским и дочерним процессами. Содержимое файла уязвимо для атак через дочерний процесс.

Исправление - закрыть и снова открыть унаследованный дескриптор файла

После создания дескриптора файла проверьте файл на наличие изменений. Затем закройте унаследованный дескриптор файла в дочернем процессе и снова откройте его в режиме только для чтения.

# include <stdio.h>
# include <stdlib.h>
# include <string.h>
# include <unistd.h>
# include <fcntl.h>
# include <sys/types.h>
# include <sys/stat.h>


const char *test_file="/home/user/test.txt";

void func(void)
{
    char c;
    pid_t pid;

    /* Get the state of file for further file tampering checking */
	
	/* create file descriptor in read and write mode */
    int fd = open(test_file, O_RDWR);  
    if (fd == -1)
    {
        /* Handle error */
		abort();
    }

    /* Be sure the file was not tampered with while opening */
	
	/* fork process */

    pid = fork();
    if (pid == -1)
    {
        /* Handle error */
        (void)close(fd);
		abort();
    }
    else if (pid == 0)
    {  /* Close file descriptor in child process and repoen 
		it in read only mode */
		
        (void)close(fd);
        fd = open(test_file, O_RDONLY); 
        if (fd == -1)
        {
            /* Handle error */
			abort();
        }


        (void)read(fd, &c, 1);
        (void)close(fd);
    }
    else
    {  /* Parent acceses original file descriptor */
        (void)read(fd, &c, 1);
        (void)close(fd);
    }
}

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

Группа: Правило 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 Университет Карнеги-Меллон, со специальным разрешением от его Института программного обеспечения.

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

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