Страница ядра Linux C мешает работе с предыдущей переменной - PullRequest
0 голосов
/ 23 октября 2018

Я хочу подключить 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 Ответ

0 голосов
/ 23 октября 2018

dentry_path_raw не выделяет имя файла (строку) для вас;он копирует его в предоставленный вами буфер памяти.Когда вы освобождаете эту страницу, имя файла становится висячей ссылкой.Было бы лучше, если бы вы допустили ошибку страницы при обращении к ней, но была бы цена за производительность, если бы free_page немедленно обновил отображения страниц.

имя файла будет указывать где-то в середине буфера, который вы предоставляетеТаким образом, вы можете освободить его в вызывающем абоненте через:

free_page((uintptr_t)filename & PAGE_MASK);
...