register_kprobe() returns EINVAL 在包含结构时没有额外的内存
register_kprobe() returns EINVAL without additional memory on containing struct
我写了一个内核模块(一个字符设备),每当我写入模块时它都会注册新的 KProbes。
我有一个包含 struct kprobe
的结构。当我调用 register_kprobe()
时,它 returns -EINVAL
。但是当我向(可能还有一些其他数据类型)添加一个虚拟字符数组时,KProbe 注册成功。
探针注册
struct my_struct *container = kmalloc(sizeof(struct my_struct));
(container->probe).addr = (kprobe_opcode_t *) kallsyms_lookup_name("my_exported_fn"); /* my_exported_fn is in code section */
(container->probe).pre_handler = Pre_Handler;
(container->probe).post_handler = Post_Handler;
register_probe(&container->probe);
/* Returns -EINVAL if my_struct contains only `struct kprobe`. */
不工作:
struct my_struct {
struct kprobe probe;
}
工作:
struct my_struct {
char dummy[512]; /* At 512, it gets consistently registered. At 256, sometimes (maybe one out of 5 - 10 times get registered) */
struct kprobe probe;
}
为什么结构中需要这个额外的内存位?
这可能是否是未对齐的内存访问,但在这种特殊情况下(我指的是编辑前的原始代码)我怀疑数据未正确初始化。即,register_kprobe()
calls kprobe_addr()
function which in turn implies the following check:
if ((symbol_name && addr) || (!symbol_name && !addr))
goto invalid;
...
invalid:
return ERR_PTR(-EINVAL);
因此,如果您确实初始化了 addr
而没有初始化 symbol_name
,后者在某些情况下可能是垃圾指针。也就是说,kmalloc()
不会将分配的内存置零,此外,根据请求的大小,它可能会从不同的 池 中获取合适大小的内存对象(有不同的 pools 来提供不同大小的对象),当你人为地增加结构的大小时,kmalloc()
必须从一个合适的池中分配一个更大的对象。从这个角度来看,这样的对象 可能 偶尔不包含垃圾的可能性很大(因为大块请求的频率较低)。
总而言之,我建议将内存块归零或使用kzalloc()
。
我写了一个内核模块(一个字符设备),每当我写入模块时它都会注册新的 KProbes。
我有一个包含 struct kprobe
的结构。当我调用 register_kprobe()
时,它 returns -EINVAL
。但是当我向(可能还有一些其他数据类型)添加一个虚拟字符数组时,KProbe 注册成功。
探针注册
struct my_struct *container = kmalloc(sizeof(struct my_struct));
(container->probe).addr = (kprobe_opcode_t *) kallsyms_lookup_name("my_exported_fn"); /* my_exported_fn is in code section */
(container->probe).pre_handler = Pre_Handler;
(container->probe).post_handler = Post_Handler;
register_probe(&container->probe);
/* Returns -EINVAL if my_struct contains only `struct kprobe`. */
不工作:
struct my_struct {
struct kprobe probe;
}
工作:
struct my_struct {
char dummy[512]; /* At 512, it gets consistently registered. At 256, sometimes (maybe one out of 5 - 10 times get registered) */
struct kprobe probe;
}
为什么结构中需要这个额外的内存位?
这可能是否是未对齐的内存访问,但在这种特殊情况下(我指的是编辑前的原始代码)我怀疑数据未正确初始化。即,register_kprobe()
calls kprobe_addr()
function which in turn implies the following check:
if ((symbol_name && addr) || (!symbol_name && !addr))
goto invalid;
...
invalid:
return ERR_PTR(-EINVAL);
因此,如果您确实初始化了 addr
而没有初始化 symbol_name
,后者在某些情况下可能是垃圾指针。也就是说,kmalloc()
不会将分配的内存置零,此外,根据请求的大小,它可能会从不同的 池 中获取合适大小的内存对象(有不同的 pools 来提供不同大小的对象),当你人为地增加结构的大小时,kmalloc()
必须从一个合适的池中分配一个更大的对象。从这个角度来看,这样的对象 可能 偶尔不包含垃圾的可能性很大(因为大块请求的频率较低)。
总而言之,我建议将内存块归零或使用kzalloc()
。