Livepatching APIs

Livepatch Enablement

intklp_enable_patch(structklp_patch*patch)

enable the livepatch

Parameters

structklp_patch*patch

patch to be enabled

Description

Initializes the data structure associated with the patch, creates the sysfsinterface, performs the needed symbol lookups and code relocations,registers the patched functions with ftrace.

This function is supposed to be called from the livepatchmodule_init()callback.

Return

0 on success, otherwise error

Shadow Variables

void*klp_shadow_get(void*obj,unsignedlongid)

retrieve a shadow variable data pointer

Parameters

void*obj

pointer to parent object

unsignedlongid

data identifier

Return

the shadow variable data element, NULL on failure.

void*klp_shadow_alloc(void*obj,unsignedlongid,size_tsize,gfp_tgfp_flags,klp_shadow_ctor_tctor,void*ctor_data)

allocate and add a new shadow variable

Parameters

void*obj

pointer to parent object

unsignedlongid

data identifier

size_tsize

size of attached data

gfp_tgfp_flags

GFP mask for allocation

klp_shadow_ctor_tctor

custom constructor to initialize the shadow data (optional)

void*ctor_data

pointer to any data needed byctor (optional)

Description

Allocatessize bytes for new shadow variable data usinggfp_flags.The data are zeroed by default. They are further initialized byctorfunction if it is not NULL. The new shadow variable is then addedto the global hashtable.

If an existing <obj, id> shadow variable can be found, this routine willissue a WARN, exit early and return NULL.

This function guarantees that the constructor function is called only whenthe variable did not exist before. The cost is thatctor is calledin atomic context under a spin lock.

Return

the shadow variable data element, NULL on duplicate orfailure.

void*klp_shadow_get_or_alloc(void*obj,unsignedlongid,size_tsize,gfp_tgfp_flags,klp_shadow_ctor_tctor,void*ctor_data)

get existing or allocate a new shadow variable

Parameters

void*obj

pointer to parent object

unsignedlongid

data identifier

size_tsize

size of attached data

gfp_tgfp_flags

GFP mask for allocation

klp_shadow_ctor_tctor

custom constructor to initialize the shadow data (optional)

void*ctor_data

pointer to any data needed byctor (optional)

Description

Returns a pointer to existing shadow data if an <obj, id> shadowvariable is already present. Otherwise, it creates a new shadowvariable likeklp_shadow_alloc().

This function guarantees that only one shadow variable exists with the givenid for the givenobj. It also guarantees that the constructor functionwill be called only when the variable did not exist before. The cost isthatctor is called in atomic context under a spin lock.

Return

the shadow variable data element, NULL on failure.

voidklp_shadow_free(void*obj,unsignedlongid,klp_shadow_dtor_tdtor)

detach and free a <obj, id> shadow variable

Parameters

void*obj

pointer to parent object

unsignedlongid

data identifier

klp_shadow_dtor_tdtor

custom callback that can be used to unregister the variableand/or free data that the shadow variable points to (optional)

Description

This function releases the memory for this <obj, id> shadow variableinstance, callers should stop referencing it accordingly.

voidklp_shadow_free_all(unsignedlongid,klp_shadow_dtor_tdtor)

detach and free all <_, id> shadow variables

Parameters

unsignedlongid

data identifier

klp_shadow_dtor_tdtor

custom callback that can be used to unregister the variableand/or free data that the shadow variable points to (optional)

Description

This function releases the memory for all <_, id> shadow variableinstances, callers should stop referencing them accordingly.

System State Changes

structklp_state*klp_get_state(structklp_patch*patch,unsignedlongid)

get information about system state modified by the given patch

Parameters

structklp_patch*patch

livepatch that modifies the given system state

unsignedlongid

custom identifier of the modified system state

Description

Checks whether the given patch modifies the given system state.

The function can be called either from pre/post (un)patchcallbacks or from the kernel code added by the livepatch.

Return

pointer tostructklp_state when found, otherwise NULL.

structklp_state*klp_get_prev_state(unsignedlongid)

get information about system state modified by the already installed livepatches

Parameters

unsignedlongid

custom identifier of the modified system state

Description

Checks whether already installed livepatches modify the givensystem state.

The same system state can be modified by more non-cumulativelivepatches. It is expected that the latest livepatch hasthe most up-to-date information.

The function can be called only during transition when a newlivepatch is being enabled or when such a transition is reverted.It is typically called only from pre/post (un)patchcallbacks.

Return

pointer to the lateststructklp_state from alreadyinstalled livepatches, NULL when not found.

Object Types

structklp_func

function structure for live patching

Definition:

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;};

Members

old_name

name of the function to be patched

new_func

pointer to the patched function code

old_sympos

a hint indicating which symbol position the old functioncan be found (optional)

old_func

pointer to the function being patched

kobj

kobject for sysfs resources

node

list node for klp_object func_list

stack_node

list node for klp_ops func_stack list

old_size

size of the old function

new_size

size of the new function

nop

temporary patch to use the original code again; dyn. allocated

patched

the func has been added to the klp_ops list

transition

the func is currently being applied or reverted

Description

The patched and transition variables define the func’s patching state. Whenpatching, a func is always in one of the following states:

patched=0 transition=0: unpatchedpatched=0 transition=1: unpatched, temporary starting statepatched=1 transition=1: patched, may be visible to some taskspatched=1 transition=0: patched, visible to all tasks

And when unpatching, it goes in the reverse order:

patched=1 transition=0: patched, visible to all taskspatched=1 transition=1: patched, may be visible to some taskspatched=0 transition=1: unpatched, temporary ending statepatched=0 transition=0: unpatched

structklp_object

kernel object structure for live patching

Definition:

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;};

Members

name

module name (or NULL for vmlinux)

funcs

function entries for functions to be patched in the object

callbacks

functions to be executed pre/post (un)patching

kobj

kobject for sysfs resources

func_list

dynamic list of the function entries

node

list node for klp_patch obj_list

mod

kernel module associated with the patched object(NULL for vmlinux)

dynamic

temporary object for nop functions; dynamically allocated

patched

the object’s funcs have been added to the klp_ops list

structklp_state

state of the system modified by the livepatch

Definition:

struct klp_state {    unsigned long id;    unsigned int version;    void *data;};

Members

id

system state identifier (non-zero)

version

version of the change

data

custom data

structklp_patch

patch structure for live patching

Definition:

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;};

Members

mod

reference to the live patch module

objs

object entries for kernel objects to be patched

states

system states that can get modified

replace

replace all actively used patches

list

list node for global list of actively used patches

kobj

kobject for sysfs resources

obj_list

dynamic list of the object entries

enabled

the patch is enabled (but operation may be incomplete)

forced

was involved in a forced transition

free_work

patch cleanup from workqueue-context

finish

for waiting till it is safe to remove the patch module