^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) ===================================
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) Atomic Replace & Cumulative Patches
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) ===================================
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) There might be dependencies between livepatches. If multiple patches need
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) to do different changes to the same function(s) then we need to define
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) an order in which the patches will be installed. And function implementations
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) from any newer livepatch must be done on top of the older ones.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) This might become a maintenance nightmare. Especially when more patches
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) modified the same function in different ways.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) An elegant solution comes with the feature called "Atomic Replace". It allows
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) creation of so called "Cumulative Patches". They include all wanted changes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) from all older livepatches and completely replace them in one transition.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) Usage
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) -----
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) The atomic replace can be enabled by setting "replace" flag in struct klp_patch,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) for example::
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) static struct klp_patch patch = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) .mod = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) .objs = objs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) .replace = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) All processes are then migrated to use the code only from the new patch.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) Once the transition is finished, all older patches are automatically
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) disabled.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) Ftrace handlers are transparently removed from functions that are no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) longer modified by the new cumulative patch.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) As a result, the livepatch authors might maintain sources only for one
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) cumulative patch. It helps to keep the patch consistent while adding or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) removing various fixes or features.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) Users could keep only the last patch installed on the system after
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) the transition to has finished. It helps to clearly see what code is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) actually in use. Also the livepatch might then be seen as a "normal"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) module that modifies the kernel behavior. The only difference is that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) it can be updated at runtime without breaking its functionality.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) Features
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) --------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) The atomic replace allows:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) - Atomically revert some functions in a previous patch while
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) upgrading other functions.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) - Remove eventual performance impact caused by core redirection
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) for functions that are no longer patched.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) - Decrease user confusion about dependencies between livepatches.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) Limitations:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) ------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) - Once the operation finishes, there is no straightforward way
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) to reverse it and restore the replaced patches atomically.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) A good practice is to set .replace flag in any released livepatch.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) Then re-adding an older livepatch is equivalent to downgrading
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) to that patch. This is safe as long as the livepatches do _not_ do
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) extra modifications in (un)patching callbacks or in the module_init()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) or module_exit() functions, see below.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) Also note that the replaced patch can be removed and loaded again
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) only when the transition was not forced.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) - Only the (un)patching callbacks from the _new_ cumulative livepatch are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) executed. Any callbacks from the replaced patches are ignored.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) In other words, the cumulative patch is responsible for doing any actions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) that are necessary to properly replace any older patch.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) As a result, it might be dangerous to replace newer cumulative patches by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) older ones. The old livepatches might not provide the necessary callbacks.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) This might be seen as a limitation in some scenarios. But it makes life
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) easier in many others. Only the new cumulative livepatch knows what
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) fixes/features are added/removed and what special actions are necessary
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) for a smooth transition.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) In any case, it would be a nightmare to think about the order of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) the various callbacks and their interactions if the callbacks from all
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) enabled patches were called.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) - There is no special handling of shadow variables. Livepatch authors
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) must create their own rules how to pass them from one cumulative
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) patch to the other. Especially that they should not blindly remove
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) them in module_exit() functions.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) A good practice might be to remove shadow variables in the post-unpatch
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) callback. It is called only when the livepatch is properly disabled.