brintos

brintos / linux-shallow public Read only

0
0
Text · 5.1 KiB · 9144457 Raw
134 lines · plain
1======================2(Un)patching Callbacks3======================4 5Livepatch (un)patch-callbacks provide a mechanism for livepatch modules6to execute callback functions when a kernel object is (un)patched.  They7can be considered a **power feature** that **extends livepatching abilities**8to include:9 10  - Safe updates to global data11 12  - "Patches" to init and probe functions13 14  - Patching otherwise unpatchable code (i.e. assembly)15 16In most cases, (un)patch callbacks will need to be used in conjunction17with memory barriers and kernel synchronization primitives, like18mutexes/spinlocks, or even stop_machine(), to avoid concurrency issues.19 201. Motivation21=============22 23Callbacks differ from existing kernel facilities:24 25  - Module init/exit code doesn't run when disabling and re-enabling a26    patch.27 28  - A module notifier can't stop a to-be-patched module from loading.29 30Callbacks are part of the klp_object structure and their implementation31is specific to that klp_object.  Other livepatch objects may or may not32be patched, irrespective of the target klp_object's current state.33 342. Callback types35=================36 37Callbacks can be registered for the following livepatch actions:38 39  * Pre-patch40                 - before a klp_object is patched41 42  * Post-patch43                 - after a klp_object has been patched and is active44                   across all tasks45 46  * Pre-unpatch47                 - before a klp_object is unpatched (ie, patched code is48                   active), used to clean up post-patch callback49                   resources50 51  * Post-unpatch52                 - after a klp_object has been patched, all code has53                   been restored and no tasks are running patched code,54                   used to cleanup pre-patch callback resources55 563. How it works57===============58 59Each callback is optional, omitting one does not preclude specifying any60other.  However, the livepatching core executes the handlers in61symmetry: pre-patch callbacks have a post-unpatch counterpart and62post-patch callbacks have a pre-unpatch counterpart.  An unpatch63callback will only be executed if its corresponding patch callback was64executed.  Typical use cases pair a patch handler that acquires and65configures resources with an unpatch handler tears down and releases66those same resources.67 68A callback is only executed if its host klp_object is loaded.  For69in-kernel vmlinux targets, this means that callbacks will always execute70when a livepatch is enabled/disabled.  For patch target kernel modules,71callbacks will only execute if the target module is loaded.  When a72module target is (un)loaded, its callbacks will execute only if the73livepatch module is enabled.74 75The pre-patch callback, if specified, is expected to return a status76code (0 for success, -ERRNO on error).  An error status code indicates77to the livepatching core that patching of the current klp_object is not78safe and to stop the current patching request.  (When no pre-patch79callback is provided, the transition is assumed to be safe.)  If a80pre-patch callback returns failure, the kernel's module loader will:81 82  - Refuse to load a livepatch, if the livepatch is loaded after83    targeted code.84 85    or:86 87  - Refuse to load a module, if the livepatch was already successfully88    loaded.89 90No post-patch, pre-unpatch, or post-unpatch callbacks will be executed91for a given klp_object if the object failed to patch, due to a failed92pre_patch callback or for any other reason.93 94If a patch transition is reversed, no pre-unpatch handlers will be run95(this follows the previously mentioned symmetry -- pre-unpatch callbacks96will only occur if their corresponding post-patch callback executed).97 98If the object did successfully patch, but the patch transition never99started for some reason (e.g., if another object failed to patch),100only the post-unpatch callback will be called.101 1024. Use cases103============104 105Sample livepatch modules demonstrating the callback API can be found in106samples/livepatch/ directory.  These samples were modified for use in107kselftests and can be found in the lib/livepatch directory.108 109Global data update110------------------111 112A pre-patch callback can be useful to update a global variable.  For113example, commit 75ff39ccc1bd ("tcp: make challenge acks less predictable")114changes a global sysctl, as well as patches the tcp_send_challenge_ack()115function.116 117In this case, if we're being super paranoid, it might make sense to118patch the data *after* patching is complete with a post-patch callback,119so that tcp_send_challenge_ack() could first be changed to read120sysctl_tcp_challenge_ack_limit with READ_ONCE.121 122__init and probe function patches support123-----------------------------------------124 125Although __init and probe functions are not directly livepatch-able, it126may be possible to implement similar updates via pre/post-patch127callbacks.128 129The commit 48900cb6af42 ("virtio-net: drop NETIF_F_FRAGLIST") change the way that130virtnet_probe() initialized its driver's net_device features.  A131pre/post-patch callback could iterate over all such devices, making a132similar change to their hw_features value.  (Client functions of the133value may need to be updated accordingly.)134