{"push_id":1445711719,"size":3,"distinct_size":3,"ref":"refs/heads/livepatch-consistency","head":"10615628670d4c03cfa740b8ca7c1bff1d328c4c","before":"df13053c388f773cedc88f80c7f2b9efc96cb591","commits":[{"sha":"e8978ec56f4840fa8546a985b3defaeef2e4a503","author":{"name":"Josh Poimboeuf","email":"e3c4f83d6dbbf85df94c8b24fb0cf20a5e953120@redhat.com"},"message":"livepatch: change to a per-task consistency model\n\nChange livepatch to use a basic per-task consistency model.  This is the\nfoundation which will eventually enable us to patch those ~10% of\nsecurity patches which change function or data semantics.  This is the\nbiggest remaining piece needed to make livepatch more generally useful.\n\nThis code stems from the design proposal made by Vojtech [1] in November\n2014.  It's a hybrid of kGraft and kpatch: it uses kGraft's per-task\nconsistency and syscall barrier switching combined with kpatch's stack\ntrace switching.  There are also a number of fallback options which make\nit quite flexible.\n\nPatches are applied on a per-task basis, when the task is deemed safe to\nswitch over.  When a patch is enabled, livepatch enters into a\ntransition state where tasks are converging to the patched state.\nUsually this transition state can complete in a few seconds.  The same\nsequence occurs when a patch is disabled, except the tasks converge from\nthe patched state to the unpatched state.\n\nAn interrupt handler inherits the patched state of the task it\ninterrupts.  The same is true for forked tasks: the child inherits the\npatched state of the parent.\n\nLivepatch uses several complementary approaches to determine when it's\nsafe to patch tasks:\n\n1. The first and most effective approach is stack checking of sleeping\n   tasks.  If no affected functions are on the stack of a given task,\n   the task is patched.  In most cases this will patch most or all of\n   the tasks on the first try.  Otherwise it'll keep trying\n   periodically.  This option is only available if the architecture has\n   reliable stacks (HAVE_RELIABLE_STACKTRACE).\n\n2. The second approach, if needed, is kernel exit switching.  A\n   task is switched when it returns to user space from a system call, a\n   user space IRQ, or a signal.  It's useful in the following cases:\n\n   a) Patching I/O-bound user tasks which are sleeping on an affected\n      function.  In this case you have to send SIGSTOP and SIGCONT to\n      force it to exit the kernel and be patched.\n   b) Patching CPU-bound user tasks.  If the task is highly CPU-bound\n      then it will get patched the next time it gets interrupted by an\n      IRQ.\n   c) Applying patches for architectures which don't yet have\n      HAVE_RELIABLE_STACKTRACE.  In this case you'll have to signal\n      most of the tasks on the system.  However this isn't a complete\n      solution, because there's currently no way to patch kthreads\n      without HAVE_RELIABLE_STACKTRACE.\n\n   Note: since idle \"swapper\" tasks don't ever exit the kernel, they\n   instead have a klp_update_patch_state() call in the idle loop which\n   allows them to patched before the CPU enters the idle state.\n\n3. A third approach (not yet implemented) is planned for the case where\n   a kthread is sleeping on an affected function.  In that case we could\n   kick the kthread with a signal and then try to patch the task from\n   the to-be-patched function's livepatch ftrace handler when it\n   re-enters the function.  This will require\n   HAVE_RELIABLE_STACKTRACE.\n\nAll the above approaches may be skipped by setting the 'immediate' flag\nin the 'klp_patch' struct, which will patch all tasks immediately.  This\ncan be useful if the patch doesn't change any function or data\nsemantics.  Note that, even with this flag set, it's possible that some\ntasks may still be running with an old version of the function, until\nthat function returns.\n\nThere's also an 'immediate' flag in the 'klp_func' struct which allows\nyou to specify that certain functions in the patch can be applied\nwithout per-task consistency.  This might be useful if you want to patch\na common function like schedule(), and the function change doesn't need\nconsistency but the rest of the patch does.\n\nFor architectures which don't have HAVE_RELIABLE_STACKTRACE, there are\ntwo options:\n\na) the user can set the patch->immediate flag which causes all tasks to\n   be patched immediately.  This option should be used with care, only\n   when the patch doesn't change any function or data semantics; or\n\nb) use the kernel exit switching approach (this is the default).\n   Note the patching will never complete because there's no currently no\n   way to patch kthreads without HAVE_RELIABLE_STACKTRACE.\n\nThe /sys/kernel/livepatch/<patch>/transition file shows whether a patch\nis in transition.  Only a single patch (the topmost patch on the stack)\ncan be in transition at a given time.  A patch can remain in transition\nindefinitely, if any of the tasks are stuck in the initial patch state.\n\nA transition can be reversed and effectively canceled by writing the\nopposite value to the /sys/kernel/livepatch/<patch>/enabled file while\nthe transition is in progress.  Then all the tasks will attempt to\nconverge back to the original patch state.\n\n[1] https://lkml.kernel.org/r/20141107140458.GA21774@suse.cz\n\nSigned-off-by: Josh Poimboeuf <jpoimboe@redhat.com>","distinct":true,"url":"https://api.github.com/repos/jpoimboe/linux/commits/e8978ec56f4840fa8546a985b3defaeef2e4a503"},{"sha":"213d7119025c7e92545bb9974bc000e39d01df37","author":{"name":"Josh Poimboeuf","email":"e3c4f83d6dbbf85df94c8b24fb0cf20a5e953120@redhat.com"},"message":"livepatch: add /proc/<pid>/patch_state\n\nExpose the per-task patch state value so users can determine which tasks\nare holding up completion of a patching operation.\n\nSigned-off-by: Josh Poimboeuf <jpoimboe@redhat.com>","distinct":true,"url":"https://api.github.com/repos/jpoimboe/linux/commits/213d7119025c7e92545bb9974bc000e39d01df37"},{"sha":"10615628670d4c03cfa740b8ca7c1bff1d328c4c","author":{"name":"Miroslav Benes","email":"25c8fd31c7fef6141597bc9781b81a4645d27859@suse.cz"},"message":"livepatch: allow removal of a disabled patch\n\nCurrently we do not allow patch module to unload since there is no\nmethod to determine if a task is still running in the patched code.\n\nThe consistency model gives us the way because when the unpatching\nfinishes we know that all tasks were marked as safe to call an original\nfunction. Thus every new call to the function calls the original code\nand at the same time no task can be somewhere in the patched code,\nbecause it had to leave that code to be marked as safe.\n\nWe can safely let the patch module go after that.\n\nCompletion is used for synchronization between module removal and sysfs\ninfrastructure in a similar way to commit 942e443127e9 (\"module: Fix\nmod->mkobj.kobj potentially freed too early\").\n\nNote that we still do not allow the removal for immediate model, that is\nno consistency model. The module refcount may increase in this case if\nsomebody disables and enables the patch several times. This should not\ncause any harm.\n\nWith this change a call to try_module_get() is moved to\n__klp_enable_patch from klp_register_patch to make module reference\ncounting symmetric (module_put() is in a patch disable path) and to\nallow to take a new reference to a disabled module when being enabled.\n\nAlso all kobject_put(&patch->kobj) calls are moved outside of klp_mutex\nlock protection to prevent a deadlock situation when\nklp_unregister_patch is called and sysfs directories are removed. There\nis no need to do the same for other kobject_put() callsites as we\ncurrently do not have their sysfs counterparts.\n\nSigned-off-by: Miroslav Benes <mbenes@suse.cz>\nSigned-off-by: Josh Poimboeuf <jpoimboe@redhat.com>","distinct":true,"url":"https://api.github.com/repos/jpoimboe/linux/commits/10615628670d4c03cfa740b8ca7c1bff1d328c4c"}]}
{"actor":{"display_login":"jpoimboe"}}