Tag: linux kernel

Netfilter字符串模块示例用法

任何人都可以指出一些使用xt_string模块和netfilter的例子或提供一个例子。 我想要做的是编写netfilter模块,它将在skb-> data字段中丢弃包含某个字符串的数据包。 我最初尝试简单地strnstr(skb->data, “mystring”, strlen(“mystring”))但这似乎是不正确的方法解决这个问题(它似乎没有工作,因为我没有看到任何数据包被丢弃) 。 提前致谢

如何正确使用copy_from_user?

我试图使用以下函数将值从用户空间复制到内核空间: static ssize_t device_write(struct file *filp, const char *buff, size_t len, loff_t *off) { unsigned long copy=0; int desp=0; copy = copy_from_user(&desp, &len, 4); printk(KERN_ALERT “copy: %lx\n”, copy); printk(KERN_ALERT “desp: %d\n”, desp); } 其中“len”是用户空间中存在的变量,我想将其复制到内核空间中的“desp” 我从用户空间调用的函数是(根据file_operations结构,write是device_write): write (fd,buffer,8, &off); 当我打印应该存储在“desp”中的值总是0(应该是8)。 我的代码有什么问题? 我一直在看几个例子,我实现了很多变化,但都没有。

在执行期间访问.eh_frame数据

我正在尝试从其中访问正在运行的程序的.eh_frame部分的内容(具体来说,该程序是Linux内核2.6.34.8)。 .eh_frame包含用于exception处理的有用数据,我想在内核代码内部使用它。 该部分已由gcc编写( readelf -a vmlinux.o包含.eh_frame ),问题是从代码中读取它。 我很确定精灵格式的文档说在代码执行期间可以访问.eh_frame 。 我查看了glibc的源代码,以寻找.eh_frame用法,并在sysdeps/generic/sysdep.h找到了大多数CFA指令的宏,但没有找到加载.eh_frame数据的实际代码。 是否需要修改加载内核以从文件加载数据的过程,或者.eh_frame info / .eh_frame_hdr段指针存储在某处作为宏/汇编程序名称(因此可以将其提取到C变量中)?

Netlink多播内核组

我试图实现的任务实际上非常简单(将字符串“TEST”多播到userland守护程序),但内核模块不能编译。 它会因错误而停止: passing argument 4 of ‘genlmsg_multicast_allns’ makes integer from pointer without a cast [enabled by default] 但它不应该只是我定义的组播组吗? 以下是“澄清”的代码: #include #include #include #include #include #include #include struct sock *nl_sk = NULL; static void daemon(void){ struct sk_buff *skb; void* msg_head; unsigned char *msg; struct genl_family my_genl_family = { .id = GENL_ID_GENERATE, .hdrsize = 0, .name = […]

什么是word_at_a_time.h中的has_zero和find_zero用于

在linux内核中,inlucde / linux / word_at_a_time.h有两个函数: static inline long find_zero(unsigned long mask) { long byte = 0; #ifdef CONFIG_64BIT if (mask >> 32) mask >>= 32; else byte = 4; #endif if (mask >> 16) mask >>= 16; else byte += 2; return (mask >> 8) ? byte : byte + 1; } static inline bool […]

为什么我们需要list_for_each_safe()来删除内核链表中的节点?

我正在学习如何使用list.h中的内核链表API。 我了解到,当使用list_del()而不是使用list_for_each()删除节点时,我需要使用list_for_each() 。 list_for_each_safe()代码: #define list_for_each_safe(pos, n, head) \ for (pos = (head)->next, n = pos->next; pos != (head); \ pos = n, n = pos->next) list_for_each()代码: for (pos = (head)->next; pos != (head); pos = pos->next) 我注意到它们都非常相似,只是_safe版本需要一个额外的参数用作’临时存储’(这里说明, list.h )。 我知道何时应用相应的function, _safe版本用于删除,正常版本用于访问,但我很好奇额外的参数如何使其“安全”? 请考虑以下内容,我使用list_for_each_safe()删除链表中的每个节点: struct kool_list{ int to; struct list_head list; int from; }; struct kool_list […]

挥发性及其有害影响

我是嵌入式开发人员,在使用I / O端口时使用volatile关键字。 但是我的项目经理建议使用volatile关键字是有害的并且有很多缺点,但我发现大多数情况下volatile在嵌入式编程中很有用,据我所知,volatile在内核代码中是有害的,因为我们代码的更改将变为不可预知的。 嵌入式系统中使用volatile还有什么缺点吗?

取消引用proc_dir_entry指针导致Linux 3.11及更高版本上的编译错误

我试图按照这里给出的示例rootkit https://github.com/ivyl/rootkit 我修改了这个例子,以便我可以在linux 3.11版本上编译它。 我发现最新的linux版本停止支持几个API,例如create_proc_entry,readdir已经被迭代等替换。 在Linux版本是3.11.0-23我还观察到我的include目录不包含internal.h,以便有完整的proc_dir_entry定义。 在linux上的较低版本(<3.10),我们在proc_fs.h文件中定义了proc_dir_entry。 修改后的rootkit文件如下所示: #include #include #include #include #include #include //#include “fs/proc/internal.h” #define MIN(a,b) \ ({ typeof (a) _a = (a); \ typeof (b) _b = (b); \ _a < _b ? _a : _b; }) #define MAX_PIDS 50 MODULE_LICENSE("Dual BSD/GPL"); MODULE_AUTHOR("Arkadiusz Hiler”); MODULE_AUTHOR(“Michal Winiarski”); //STATIC VARIABLES SECTION //we don’t want […]

“{{}} while(0)”在内核代码中的作用是什么?

可能重复: 当我们定义宏时,do(0)有什么用? 为什么在C / C ++宏中有时会出现无意义的do / while和if / else语句? C多行宏:do / while(0)vs scope block 我已经看过很多这样的用法,以前我是程序员想要轻松打破一段代码。 为什么我们需要在这里执行while {…} while(0)循环? 我们试图告诉编译器一些东西吗? 例如,在Linux内核2.6.25中,包含/ asm-ia64 / system.h /* * – clearing psr.i is implicitly serialized (visible by next insn) * – setting psr.i requires data serialization * – we need a stop-bit before reading PSR because we sometimes […]

为什么在工作交错时TCP写入延迟会更糟?

我一直在分析TCP延迟(特别是从用户空间到小消息的内核空间的write ),以便对write的延迟有所了解(确认这可能是特定于上下文的)。 我注意到测试之间存在很大的不一致,这对我来说似乎很相似,而且我很想知道差异来自何处。 我知道微基准测试可能会有问题,但我仍然觉得我缺少一些基本的理解(因为延迟差异是~10倍)。 设置是我有一个C ++ TCP服务器接受一个客户端连接(来自同一CPU上的另一个进程),并且在与客户端连接时进行20次系统调用以write套接字,一次发送一个字节。 服务器的完整代码将在本文末尾复制。 这是使用boost/timer每次write时间输出(增加~1 mic的噪声): $ clang++ -std=c++11 -stdlib=libc++ tcpServerStove.cpp -O3; ./a.out 18 mics 3 mics 3 mics 4 mics 3 mics 3 mics 4 mics 3 mics 5 mics 3 mics … 我可靠地发现第一次write明显慢于其他write 。 如果我在一个计时器中包装10,000个write调用,则每次write的平均值为2微秒,但第一个调用始终是15个以上的麦克风。 为什么会出现这种“升温”现象? 相关地,我运行了一个实验,在每个write调用之间我做了一些阻止CPU工作(计算一个大的素数)。 这会导致所有 write调用都很慢: $ clang++ -std=c++11 -stdlib=libc++ tcpServerStove.cpp -O3; ./a.out 20 mics 23 […]