Проблема
Воздействие дескриптора файла дочернего процесса происходит, когда процесс разветвлен, и дочерний процесс использует дескрипторы файлов, наследованные от родительского процесса.
Риск
Когда вы разветвляете дочерний процесс, дескрипторы файлов копируются с родительского процесса, что означает, что можно перенести параллельные операции на том же файле. Использование того же дескриптора файла в родительских и дочерних процессах может привести к условиям состязания, которые не могут быть отловлены во время стандартной отладки. Если вы правильно не управляете полномочиями дескриптора файла и привилегиями, содержимое файла уязвимо для нападений, предназначающихся для дочернего процесса.
Фиксация
Проверяйте, что файл не был изменен прежде, чем разветвить процесс. Закройте все наследованные дескрипторы файлов и вновь откройте их с более строгими полномочиями и привилегиями, такими как разрешение только для чтения.
Пример - к дескриптору файла получают доступ от разветвленного процесса
# 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);
}
}