Livepatching APIs

Livepatch 啟用

int klp_enable_patch(struct klp_patch *patch)

啟用 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_state *klp_get_state(struct klp_patch *patch, unsigned long id)

獲取有關給定補丁修改的系統狀態的資訊

引數

struct klp_patch *patch

修改給定系統狀態的 livepatch

unsigned long id

修改的系統狀態的自定義識別符號

描述

檢查給定補丁是否修改了給定的系統狀態。

該函式可以從預/後(取消)補丁回撥或從 livepatch 新增的核心程式碼中呼叫。

返回值

指向 struct klp_state 的指標,如果找到,否則為 NULL。

struct klp_state *klp_get_prev_state(unsigned long id)

獲取有關已安裝的 livepatch 修改的系統狀態的資訊

引數

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

用於等待直到可以安全地刪除補丁模組