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
Удар: носитель
ID CWE: 362

Введенный в R2017b