Livepatching APIs¶
Livepatch 启用¶
参数
struct klp_patch *patch
要启用的补丁
描述
初始化与补丁相关联的数据结构,创建 sysfs 接口,执行所需的符号查找和代码重定位,使用 ftrace 注册已修补的函数。
此函数应从 livepatch module_init()
回调中调用。
返回值
成功时返回 0,否则返回错误
影子变量¶
-
void *klp_shadow_get(void *obj, unsigned long id)¶
检索影子变量数据指针
参数
void *obj
指向父对象的指针
unsigned long id
数据标识符
返回值
影子变量数据元素,失败时为 NULL。
-
void *klp_shadow_alloc(void *obj, unsigned long id, size_t size, gfp_t gfp_flags, klp_shadow_ctor_t ctor, void *ctor_data)¶
分配并添加一个新的影子变量
参数
void *obj
指向父对象的指针
unsigned long id
数据标识符
size_t size
附加数据的大小
gfp_t gfp_flags
分配的 GFP 掩码
klp_shadow_ctor_t ctor
用于初始化影子数据的自定义构造函数(可选)
void *ctor_data
指向 **ctor** 所需的任何数据的指针(可选)
描述
使用 **gfp_flags** 为新的影子变量数据分配 **size** 个字节。 默认情况下数据被清零。 如果 **ctor** 函数不为 NULL,则数据将由该函数进一步初始化。 然后将新的影子变量添加到全局哈希表。
如果可以找到现有的 <obj, id> 影子变量,此例程将发出 WARN,提前退出并返回 NULL。
此函数保证仅当变量之前不存在时才调用构造函数。 这样做的代价是在自旋锁下的原子上下文中调用 **ctor**。
返回值
影子变量数据元素,重复或失败时为 NULL。
-
void *klp_shadow_get_or_alloc(void *obj, unsigned long id, size_t size, gfp_t gfp_flags, klp_shadow_ctor_t ctor, void *ctor_data)¶
获取现有影子变量或分配新的影子变量
参数
void *obj
指向父对象的指针
unsigned long id
数据标识符
size_t size
附加数据的大小
gfp_t gfp_flags
分配的 GFP 掩码
klp_shadow_ctor_t ctor
用于初始化影子数据的自定义构造函数(可选)
void *ctor_data
指向 **ctor** 所需的任何数据的指针(可选)
描述
如果已经存在 <obj, id> 影子变量,则返回指向现有影子数据的指针。 否则,它会像 klp_shadow_alloc()
一样创建一个新的影子变量。
此函数保证对于给定的 **obj**,只有一个具有给定 **id** 的影子变量存在。 它还保证仅当变量之前不存在时才调用构造函数。 这样做的代价是在自旋锁下的原子上下文中调用 **ctor**。
返回值
影子变量数据元素,失败时为 NULL。
-
void klp_shadow_free(void *obj, unsigned long id, klp_shadow_dtor_t dtor)¶
分离并释放 <obj, id> 影子变量
参数
void *obj
指向父对象的指针
unsigned long id
数据标识符
klp_shadow_dtor_t dtor
可用于注销变量和/或释放影子变量指向的数据的自定义回调(可选)
描述
此函数释放此 <obj, id> 影子变量实例的内存,调用者应相应地停止引用它。
-
void klp_shadow_free_all(unsigned long id, klp_shadow_dtor_t dtor)¶
分离并释放所有 <_, id> 影子变量
参数
unsigned long id
数据标识符
klp_shadow_dtor_t dtor
可用于注销变量和/或释放影子变量指向的数据的自定义回调(可选)
描述
此函数释放所有 <_, id> 影子变量实例的内存,调用者应相应地停止引用它们。
系统状态更改¶
参数
struct klp_patch *patch
修改给定系统状态的 livepatch
unsigned long id
修改的系统状态的自定义标识符
描述
检查给定补丁是否修改了给定的系统状态。
该函数可以从预/后(取消)补丁回调或从 livepatch 添加的内核代码中调用。
返回值
指向 struct klp_state
的指针,如果找到,否则为 NULL。
参数
unsigned long id
修改的系统状态的自定义标识符
描述
检查已安装的 livepatch 是否修改了给定的系统状态。
同一个系统状态可以被更多非累积性 livepatch 修改。 预计最新的 livepatch 具有最新的信息。
该函数只能在启用新 livepatch 或恢复此类转换的转换期间调用。 它通常仅从预/后(取消)补丁回调中调用。
返回值
- 指向来自已安装的 livepatch 的最新 struct klp_state 的指针,如果未找到则为 NULL。
已安装的 livepatch,如果未找到则为 NULL。
对象类型¶
-
struct klp_func¶
用于实时修补的函数结构
定义:
struct klp_func {
const char *old_name;
void *new_func;
unsigned long old_sympos;
void *old_func;
struct kobject kobj;
struct list_head node;
struct list_head stack_node;
unsigned long old_size, new_size;
bool nop;
bool patched;
bool transition;
};
成员
old_name
要修补的函数的名称
new_func
指向已修补函数代码的指针
old_sympos
指示可以在哪个符号位置找到旧函数的提示(可选)
old_func
指向正在修补的函数的指针
kobj
用于 sysfs 资源的 kobject
node
klp_object func_list 的列表节点
stack_node
klp_ops func_stack 列表的列表节点
old_size
旧函数的大小
new_size
新函数的大小
nop
用于再次使用原始代码的临时补丁; 动态分配
patched
该函数已添加到 klp_ops 列表
transition
该函数当前正在被应用或恢复
描述
patched 和 transition 变量定义了函数的修补状态。 修补时,函数始终处于以下状态之一
patched=0 transition=0: 未修补 patched=0 transition=1: 未修补,临时起始状态 patched=1 transition=1: 已修补,可能对某些任务可见 patched=1 transition=0: 已修补,对所有任务可见
取消修补时,它按相反的顺序进行
patched=1 transition=0: 已修补,对所有任务可见 patched=1 transition=1: 已修补,可能对某些任务可见 patched=0 transition=1: 未修补,临时结束状态 patched=0 transition=0: 未修补
-
struct klp_callbacks¶
预/后 live-(取消)补丁回调结构
定义:
struct klp_callbacks {
int (*pre_patch)(struct klp_object *obj);
void (*post_patch)(struct klp_object *obj);
void (*pre_unpatch)(struct klp_object *obj);
void (*post_unpatch)(struct klp_object *obj);
bool post_unpatch_enabled;
};
成员
pre_patch
在代码修补之前执行
post_patch
在代码修补之后执行
pre_unpatch
在代码取消修补之前执行
post_unpatch
在代码取消修补之后执行
post_unpatch_enabled
指示是否应运行 post-unpatch 回调的标志
描述
所有回调都是可选的。 仅当提供了 pre-patch 回调时,它才会被无条件执行。 如果父 klp_object 因任何原因而无法修补,包括从 pre-patch 回调返回的非零错误状态,则不会执行任何进一步的回调。
-
struct klp_object¶
用于实时修补的内核对象结构
定义:
struct klp_object {
const char *name;
struct klp_func *funcs;
struct klp_callbacks callbacks;
struct kobject kobj;
struct list_head func_list;
struct list_head node;
struct module *mod;
bool dynamic;
bool patched;
};
成员
name
模块名称(对于 vmlinux,则为 NULL)
funcs
要在对象中修补的函数的函数条目
callbacks
要在预/后(取消)修补期间执行的函数
kobj
用于 sysfs 资源的 kobject
func_list
函数条目的动态列表
node
klp_patch obj_list 的列表节点
mod
与已修补对象关联的内核模块(对于 vmlinux,则为 NULL)
dynamic
用于 nop 函数的临时对象; 动态分配
patched
该对象的函数已添加到 klp_ops 列表
-
struct klp_state¶
livepatch 修改的系统状态
定义:
struct klp_state {
unsigned long id;
unsigned int version;
void *data;
};
成员
id
系统状态标识符(非零)
version
更改的版本
data
自定义数据
-
struct klp_patch¶
用于实时修补的补丁结构
定义:
struct klp_patch {
struct module *mod;
struct klp_object *objs;
struct klp_state *states;
bool replace;
struct list_head list;
struct kobject kobj;
struct list_head obj_list;
bool enabled;
bool forced;
struct work_struct free_work;
struct completion finish;
};
成员
mod
对 live patch 模块的引用
objs
要修补的内核对象的对象条目
states
可以修改的系统状态
replace
替换所有主动使用的补丁
list
主动使用的补丁的全局列表的列表节点
kobj
用于 sysfs 资源的 kobject
obj_list
对象条目的动态列表
enabled
已启用补丁(但操作可能不完整)
forced
参与了强制转换
free_work
从工作队列上下文中清除补丁
finish
用于等待直到可以安全地删除补丁模块