Livepatching API¶
Livepatch 启用¶
参数
struct klp_patch *patch要启用的 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 字节。数据默认清零。如果不为 NULL,它们将进一步由 ctor 函数初始化。然后将新的影子变量添加到全局哈希表中。
如果能找到现有的 <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_state *klp_get_state(struct klp_patch *patch, unsigned long id)¶
获取有关由给定 patch 修改的系统状态的信息
参数
struct klp_patch *patch修改给定系统状态的 livepatch
unsigned long id被修改系统状态的自定义标识符
描述
检查给定的 patch 是否修改了给定的系统状态。
该函数既可以从 pre/post (un)patch 回调中调用,也可以从 livepatch 添加的内核代码中调用。
返回
找到时返回指向 struct klp_state 的指针,否则返回 NULL。
参数
unsigned long id被修改系统状态的自定义标识符
描述
检查已安装的 livepatch 是否修改了给定的系统状态。
同一个系统状态可以被多个非累积的 livepatch 修改。预计最新的 livepatch 拥有最新的信息。
该函数只能在启用新 livepatch 的过渡期间或回滚此类过渡时调用。它通常只从 pre/post (un)patch 回调中调用。
返回
指向已安装 livepatch 中最新 struct klp_state 的指针,未找到时返回 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
nodeklp_object func_list 的链表节点
stack_nodeklp_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_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在 (un)patching 前/后执行的函数
kobj用于 sysfs 资源的 kobject
func_list函数条目的动态链表
nodeklp_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用于等待直到可以安全移除 patch 模块