CERT C: Rule POS38-C

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

Описание

Управляйте определением

Остерегайтесь условий состязания при использовании ветвления и файла descriptors.[1]

Реализация Polyspace

Это средство проверки проверяет на воздействие Дескриптора файла дочернего процесса.

Примеры

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

Проблема

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

Риск

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

Фиксация

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

Пример - к дескриптору файла получают доступ от разветвленного процесса
# 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 Carnegie Mellon University, веб-сайт SEI CERT-C © 2017 Carnegie Mellon University”, CERT SEI C Кодирование Стандарта – Правил для Разработки безопасных, Надежных и Защищенных систем – 2 016 Выпусков”, © 2016 Carnegie Mellon University, and “CERT SEI Стандарт Кодирования C++ – Правил для Разработки безопасных, Надежных и Защищенных систем на C++ – 2 016 Выпусков” © 2016 Carnegie Mellon University, со специальным разрешением от его Института программной инженерии.

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

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