Back to home page

OSCL-LXR

 
 

    


0001 ===================================
0002 Atomic Replace & Cumulative Patches
0003 ===================================
0004 
0005 There might be dependencies between livepatches. If multiple patches need
0006 to do different changes to the same function(s) then we need to define
0007 an order in which the patches will be installed. And function implementations
0008 from any newer livepatch must be done on top of the older ones.
0009 
0010 This might become a maintenance nightmare. Especially when more patches
0011 modified the same function in different ways.
0012 
0013 An elegant solution comes with the feature called "Atomic Replace". It allows
0014 creation of so called "Cumulative Patches". They include all wanted changes
0015 from all older livepatches and completely replace them in one transition.
0016 
0017 Usage
0018 -----
0019 
0020 The atomic replace can be enabled by setting "replace" flag in struct klp_patch,
0021 for example::
0022 
0023         static struct klp_patch patch = {
0024                 .mod = THIS_MODULE,
0025                 .objs = objs,
0026                 .replace = true,
0027         };
0028 
0029 All processes are then migrated to use the code only from the new patch.
0030 Once the transition is finished, all older patches are automatically
0031 disabled.
0032 
0033 Ftrace handlers are transparently removed from functions that are no
0034 longer modified by the new cumulative patch.
0035 
0036 As a result, the livepatch authors might maintain sources only for one
0037 cumulative patch. It helps to keep the patch consistent while adding or
0038 removing various fixes or features.
0039 
0040 Users could keep only the last patch installed on the system after
0041 the transition to has finished. It helps to clearly see what code is
0042 actually in use. Also the livepatch might then be seen as a "normal"
0043 module that modifies the kernel behavior. The only difference is that
0044 it can be updated at runtime without breaking its functionality.
0045 
0046 
0047 Features
0048 --------
0049 
0050 The atomic replace allows:
0051 
0052   - Atomically revert some functions in a previous patch while
0053     upgrading other functions.
0054 
0055   - Remove eventual performance impact caused by core redirection
0056     for functions that are no longer patched.
0057 
0058   - Decrease user confusion about dependencies between livepatches.
0059 
0060 
0061 Limitations:
0062 ------------
0063 
0064   - Once the operation finishes, there is no straightforward way
0065     to reverse it and restore the replaced patches atomically.
0066 
0067     A good practice is to set .replace flag in any released livepatch.
0068     Then re-adding an older livepatch is equivalent to downgrading
0069     to that patch. This is safe as long as the livepatches do _not_ do
0070     extra modifications in (un)patching callbacks or in the module_init()
0071     or module_exit() functions, see below.
0072 
0073     Also note that the replaced patch can be removed and loaded again
0074     only when the transition was not forced.
0075 
0076 
0077   - Only the (un)patching callbacks from the _new_ cumulative livepatch are
0078     executed. Any callbacks from the replaced patches are ignored.
0079 
0080     In other words, the cumulative patch is responsible for doing any actions
0081     that are necessary to properly replace any older patch.
0082 
0083     As a result, it might be dangerous to replace newer cumulative patches by
0084     older ones. The old livepatches might not provide the necessary callbacks.
0085 
0086     This might be seen as a limitation in some scenarios. But it makes life
0087     easier in many others. Only the new cumulative livepatch knows what
0088     fixes/features are added/removed and what special actions are necessary
0089     for a smooth transition.
0090 
0091     In any case, it would be a nightmare to think about the order of
0092     the various callbacks and their interactions if the callbacks from all
0093     enabled patches were called.
0094 
0095 
0096   - There is no special handling of shadow variables. Livepatch authors
0097     must create their own rules how to pass them from one cumulative
0098     patch to the other. Especially that they should not blindly remove
0099     them in module_exit() functions.
0100 
0101     A good practice might be to remove shadow variables in the post-unpatch
0102     callback. It is called only when the livepatch is properly disabled.