Страница ядра Linux C мешает работе с предыдущей переменной
Я хочу зацепить read
в ядре Linux, чтобы показать, какой процесс читает файл в /home/xytao/safe
каталог.
// get absolute file path from file struct
char *get_filename(struct file *file)
{
char *buf = (char *)__get_free_page(GFP_KERNEL);
if (!buf)
{
return NULL;
}
char *filename = dentry_path_raw(file->f_path.dentry, buf, PAGE_SIZE - 1);
if (IS_ERR(filename))
{
free_page((unsigned long)buf);
return NULL;
}
free_page((unsigned long)buf);
return filename;
}
asmlinkage ssize_t fake_read(int __fd, void *__buf, size_t __nbytes)
{
char *pathname;
struct file *file;
struct path *path;
struct files_struct *files = current->files;
spin_lock(&files->file_lock);
file = fcheck_files(files, __fd);
if (!file)
{
spin_unlock(&files->file_lock);
return -ENOENT;
}
spin_unlock(&files->file_lock);
ssize_t out = real_read(__fd, __buf, __nbytes);
pathname=get_filename(file);
if (!strncmp(pathname, "/home/xytao/safe", 15))
{ fm_alert("pathname_before:%s\n", pathname);
struct file *process_file = get_task_exe_file(current);
fm_alert("process_name:%s\n", get_filename(process_file));
fm_alert("pathname_after:%s\n:", pathname);
}
return out;
}
Но похоже pathname
был изменен после получения имени процесса, и pathname
был скомпрометирован get_filename(process_file)
,
Например, после того, как я открываю /home/xytao/safe/test
Я получаю следующий вывод:
[ 1181.179485] fsmonko.fake_read: pathname_before:/home/xytao/safe/test
[ 1181.179488] fsmonko.fake_read: process_name:/usr/bin/gedit
[ 1181.179490] fsmonko.fake_read: pathname_after:/home/x/usr/bin/gedit
:
[ 1181.181590] fsmonko.fake_read: pathname_before:/home/xytao/safe/test
[ 1181.181594] fsmonko.fake_read: process_name:/usr/bin/gedit
[ 1181.181595] fsmonko.fake_read: pathname_after:/home/x/usr/bin/gedit
:
[ 1181.190503] fsmonko.fake_read: pathname_before:/home/xytao/safe/test
[ 1181.190509] fsmonko.fake_read: process_name:/usr/bin/gedit
[ 1181.190511] fsmonko.fake_read: pathname_after:/home/x/usr/bin/gedit
:
[ 1197.523906] fsmonko.fake_read: pathname_before:/home/xytao/safe/test
[ 1197.523915] fsmonko.fake_read: process_name:/usr/bin/nautilus
Как это исправить?
1 ответ
dentry_path_raw
не выделяет имя файла (строку) для вас; он копирует его в предоставленный вами буфер памяти. Когда вы освобождаете эту страницу, имя файла становится висячей ссылкой. Было бы лучше, если бы вы взяли на себя ошибку страницы, ссылаясь на нее, но была бы цена за производительность, если free_page
немедленно обновил сопоставления страниц.
имя файла будет указывать где-то посередине буфера, который вы предоставляете, так что вы можете освободить его в вызывающей стороне с помощью:
free_page((uintptr_t)filename & PAGE_MASK);