在netfilter挂钩中查找可执行发送数据包的名称

时间:2017-12-04 13:02:58

标签: c linux linux-kernel kernel-module netfilter

我正在编写一个使用netfilter挂钩来过滤TCP数据包的内核模块,需要查找发送数据包的可执行文件的路径。到目前为止,我使用了以下方法,但它打印的名称似乎与使用的可执行文件无关( / usr / lib / firefox / firefox usr / bin / telnet.netkit / usr / bin / wget )。

pid_t pid = current->pid;
struct path path;
char buff[BUFF_LEN];
snprintf (buff, BUFF_LEN, "/proc/%d/exe", pid);
if(!kern_path(buff, LOOKUP_FOLLOW, &path)) {
    struct dentry* procEntry = path.dentry;
    printk("Process: %s\n", procEntry->d_name.name);
    printk("Parent: %s\n", procEntry->d_parent->d_name.name);
}

内核日志输出: enter image description here

1 个答案:

答案 0 :(得分:2)

这看起来像是一个质量差的大学作业,我有一种明显的印象,这种东西已经出现在这里了。

您的代码很可能是从中断上下文执行的,即随机线程被中断以进行数据包处理,而“current”是指向所述随机线程的指针。这应该很容易验证,例如通过获得回溯 - 可以使用WARN_ONCE等。

通过procfs查找当前的可执行文件名称非常糟糕。 procfs必须做更多工作,并最终获得有效当前的内容。更糟糕的是,您未能找到找到的路径,因此您会泄漏资源。如果这个代码确实是从一个中断处理程序执行的,那么结果不仅是荒谬的,而且由于睡眠的可能性,不能用这种方法安全地获得。

即使你要获得“正确的”可执行文件名,整个作业也是废话。一个进程可以通过多种方式改变另一个进程的执行。从而有效地绕过你所拥有的任何过滤器。有趣的是,有一种方法可以将您的流程名称更改为其他内容而不会执行任何操作,再一次使该概念无效。

您可以做的最好的事情是按凭据过滤,但它们不是特定于流程的。原则上,您可以将selinux标签添加到文件中并按此过滤,但再次弱化。

简而言之,作业是胡说八道。