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