Исполняемый путь от fd inode в модуле ядра linux

  • Учитывая inode, который существует в /proc/**/fd/*
  • И модуль ядра Linux, которому нужно найти путь к исполняемому файлу по символической ссылке /proc/**/exe

Как я мог реализовать это так, чтобы из номера инода я получил путь к исполняемому файлу с помощью fd?


person ZedTuX    schedule 01.05.2013    source источник
comment
В своих исследованиях я нашел метод proc_fd_link (lxr .free-electrons.com/source/fs/proc/fd.c?a=avr32#L140), но недоступен из моего модуля ядра (метод не найден при компиляции.   -  person ZedTuX    schedule 01.05.2013
comment
Я также нашел макросы PDE и PROC_I (lxr.free-electrons.com/ source/include/linux/proc_fs.h), но тогда я не знаю, как найти элемент /proc/**/exe.   -  person ZedTuX    schedule 01.05.2013
comment
Индексный дескриптор может не иметь или иметь более одного пути, а пространства имен могут приводить к разным путям в разных процессах. Для чего нужен путь и почему это надо делать из модуля ядра?   -  person CL.    schedule 04.05.2013
comment
@КЛ. Это не обязательно делать в модуле ядра (и в настоящее время я реализую это в пользовательском приложении). Что вы имели в виду под Для чего вам нужен путь?   -  person ZedTuX    schedule 05.05.2013
comment
Итак, вы повторно реализуете lsof?   -  person CL.    schedule 05.05.2013
comment
Нет, я разрабатываю брандмауэр на прикладном уровне, поэтому я фильтрую исходящие пакеты для каждого процесса.   -  person ZedTuX    schedule 05.05.2013
comment
Посмотрите, как это делает lsof.   -  person CL.    schedule 05.05.2013
comment
lsof перебирает каждую папку /proc/[PID]/, я думаю, и является приложением пользовательского пространства. Я бы предпочел сделать это в модуле ядра (даже если я попробую способ пользовательского пространства), потому что я не могу себе представить, что нет метода proc_*, где я мог бы передать номер инода сокета, и я получаю указатель на /proc/[pid]/fd/*, где я мог бы подняться, чтобы получить /proc/[pid]/exe.   -  person ZedTuX    schedule 06.05.2013


Ответы (1)


Структура proc_inode и PROC_Iмакрос являются внутренними. См. [PATCH 27/28] proc: Создайте PROC_I() и PDE () внутренние макросы toprocfs [RFC].

Вместо этого как насчет перебора списка dentry inode? Вы можете использовать dentry_path_raw(), чтобы найти имя пути /*/fd/*:

//struct inode *proc_inode;

struct dentry *dentry;
pid_t pid;
int found_match = 0;

printk(KERN_DEBUG "superblock type name: %s\n", proc_inode->i_sb->s_type->name);

// An inode's dentry list is protected by the i_lock. See:
// - "dcache->d_inode->i_lock protects: i_dentry, d_u.d_alias, d_inode of aliases"
//   http://lxr.free-electrons.com/source/fs/dcache.c?v=4.0#L48
// - The implementation of d_prune_aliases()
//   http://lxr.free-electrons.com/source/fs/dcache.c?v=4.0#L882
spin_lock(&proc_inode->i_lock);
hlist_for_each_entry(dentry, &proc_inode->i_dentry, d_u.d_alias) {
    char buf[64];
    const char *path_raw;
    char c;

    path_raw = dentry_path_raw(dentry, buf, sizeof(buf));

    // dentry_path_raw() places the path into `buf'. If `buf' is not large
    // enough, then continue on to the next dentry.
    if (!(buf <= path_raw && path_raw <= buf + sizeof(buf) - 1)) {
        printk(KERN_DEBUG "`buf' not large enough, dentry_path_raw() returned %ld\n", PTR_ERR(path_raw));
        continue;
    }

    printk(KERN_DEBUG "path_raw = %s\n", path_raw);

    // We're looking to match: ^/(\d*)/fd/

    if (*path_raw++ != '/') continue;

    pid = 0;
    for (c = *path_raw; c; c = *++path_raw) {
        if ('0' <= c && c <= '9') {
            pid = 10 * pid + (c - '0');
        } else {
            break;
        }
    }

    if (*path_raw++ != '/') continue;
    if (*path_raw++ != 'f') continue;
    if (*path_raw++ != 'd') continue;
    if (*path_raw != '/' && *path_raw != '\0') continue;

    // Found a match. Break the dentry list loop.
    found_match = 1;
    printk(KERN_DEBUG "breaking dentry list loop\n");
    break;
}
spin_unlock(&proc_inode->i_lock);

if (found_match) {
    printk(KERN_DEBUG "pid = %d\n", (int)pid);
}

EDIT: я загрузил демонстрационный проект на GitHub:
https://github.com/dtrebbien/so16317923-proc-fs-kernel-module

person Daniel Trebbien    schedule 04.06.2015
comment
Спасибо ! я взгляну - person ZedTuX; 10.06.2015