File descriptor exposure to child 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);
    }
}

Информация о результатах

Группа: Безопасность
Язык: C | C++
По умолчанию: Off
Синтаксис командной строки : FILE_EXPOSURE_TO_CHILD
Влияние: Средний
ИДЕНТИФИКАТОР CWE : 362
Введенный в R2017b