issue commentdynup/kpatch
Need to document callback best practices
Can maybe also document how to add/remove sysfs files to existing dirs?
comment created time in 13 hours
issue commentdynup/kpatch
Need to document callback best practices
Also may need to mention other things discussed like how globals are harmful though I did open another issue for that.
comment created time in 14 hours
issue openeddynup/kpatch
Need to document callback best practices
Need to document the callback best practices which we defined while working on the IFU and TAA patches. Not sure whether it belongs in the author guide or in the kernel callback docs. Maybe both.
created time in 14 hours
push eventdynup/kpatch
commit sha e4b6e1ff6e3587e3d80b353089fc030dc72972fa
doc: Update broken hyperlink Referenced kernel documentation has moved from txt file to rst. Update the hyperlink to point to the correct file. Signed-off-by: Julien Thierry <[email protected]>
commit sha ea348164f6a15b9134053c4895cf75afd720e366
Merge pull request #1058 from julien-thierry/doc-link-fix doc: Update broken hyperlink
push time in 7 days
PR merged dynup/kpatch
Referenced kernel documentation has moved from txt file to rst. Update the hyperlink to point to the correct file.
Signed-off-by: Julien Thierry [email protected]
pr closed time in 7 days
issue openeddynup/kpatch
Storing state in global variables considered harmful
If a patch stores state in a global variable, and then the patch is later replaced with a newer cumulative patch, the global variable in the new patch will be distinct from the variable in the original patch, and thus won't have the original state. This is dangerous and needs to be prevented. Instead a shadow variable should be used to store global state.
Ideally the best option would be to report an error (or at least a warning) if non-rodata data is added to a patch. I'm not sure if there would be any false positive warnings. It needs to be investigated.
created time in 13 days
Pull request review commentdynup/kpatch
struct kpatch_symbol { unsigned long src;- unsigned long pos;+ unsigned long sympos;
Good point. I also don't have a strong feeling either way but I might prefer to leave it as 'sympos' despite the redundancy, because that's what we call the value upstream.
comment created time in 17 days
Pull request review commentdynup/kpatch
static void kpatch_create_patches_sections(struct kpatch_elf *kelf, /* count patched functions */ nr = 0;- list_for_each_entry(sym, &kelf->symbols, list)- if (sym->type == STT_FUNC && sym->status == CHANGED && !sym->parent)- nr++;+ list_for_each_entry(sym, &kelf->symbols, list) {+ if (sym->type != STT_FUNC || sym->status != CHANGED ||+ sym->parent)+ continue;+ nr++;
In isolation I would agree, but the benefit is that this makes the condition identical to the 2nd loop's conditional, so the reader can verify the conditions are the same and 'nr' is valid.
comment created time in 19 days
PR opened dynup/kpatch
Some long overdue cleanups to the dynrela and lookup code. In theory this should be no functional change.
pr created time in 19 days
push eventjpoimboe/kpatch
commit sha 770f5292253d6c6150b2a1757072a4731687f908
kpatch-elf: Ensure stale references are not used When freeing a kpatch_elf, another object might have symbols and sections twined with elements that are getting freed. Clear the twin references, so if they are used after the object they reference is freed, the program will crash. Signed-off-by: Julien Thierry <[email protected]>
commit sha 49a9adaf743d1cb6f32f453cb70db7185fb22c48
create-diff-object: Correlate objects related to a section at once Elements from the original object and the patched object can be correlated using their mangled names. In case an elements (section or symbol) could be matched with more than one object through mangling, make sure all elements related to a section are correlated with the corresponding elements of the twin section. Signed-off-by: Julien Thierry <[email protected]>
commit sha e49e3a59c2204b3f3783f1cc2797062bd20cfe92
create-diff-object: Rename elements getting correlated Change 935f1998752b ('create-diff-object: simplify mangled function correlation') simplified the way symbols are correlated and got rid of symbol section renaming. As a result a symbol/section can now have a CHANGED status, being correlated to an element that doesn't have the exact same name. This will cause lookups to the original object fail when creating the new patch object. So lets bring back the symbol/section renaming, but only once they have actually been correlated. Fixes: 935f1998752b ('create-diff-object: simplify mangled function correlation') Signed-off-by: Julien Thierry <[email protected]>
commit sha 852bad5e8d4c453f98423d0ba7533db62d462659
create-diff-object: Use new helpers for static local correlation Simplify static local variable correlation and renaming code by using the newly introduced helpers for section and symbol correlation. Signed-off-by: Julien Thierry <[email protected]>
commit sha 54553c062227fc291e576fc26ce2c65badcac4eb
test/unit: Update unit test submodule Include test for mangled symbol modification. Signed-off-by: Julien Thierry <[email protected]>
commit sha b53e4e3f44b9062a7cc63f0f3dd90f5bd257775d
Merge pull request #1048 from julien-thierry/correlation-rename-fixes Correlation rename fixes
commit sha 5534103a6cbab383773c48ccb36f46f6634c1167
create-diff-object: reduce indentation in kpatch_create_patches_sections() Reverse the if condition and use a 'continue' statement to reduce indentation and improve readability. Signed-off-by: Josh Poimboeuf <[email protected]>
commit sha 6a1767ce00c105b4f1e6eac9763a8540e4b57bec
lookup: remove unused testing code This testing code is no longer used. Remove it. Signed-off-by: Josh Poimboeuf <[email protected]>
commit sha ec72bd6388032f3c3d284a03a2fd073eef64cf84
lookup: rename 'value' -> 'addr' Rename 'value' to 'addr' to more accurately describe it. Signed-off-by: Josh Poimboeuf <[email protected]>
commit sha e522917752b657b7d7b2794ab3485503ca6fcedb
lookup: rename 'pos' to 'sympos' To more accurately describe its purpose. Signed-off-by: Josh Poimboeuf <[email protected]>
commit sha 1c141675c8853d489db6be785501dc85c24dd673
lookup: convert lookup functions to return bool IMO, the code is easier to follow if these functions return bool. Signed-off-by: Josh Poimboeuf <[email protected]>
commit sha 9eef74d982c52971c11f02f3c794a32b37211c39
lookup: add 'objname' to lookup table and lookup results This will be needed for the upcoming dynrela refactoring. Signed-off-by: Josh Poimboeuf <[email protected]>
commit sha 487900dc12d45a78216748de54f96475a94dd643
lookup: add duplicate symbol checks Add checks for duplicate symbols, and refactor the logic slightly. Signed-off-by: Josh Poimboeuf <[email protected]>
commit sha 2e41f281339e0216a91f0c0488919deff599403b
create-diff-object: rename lookup 'result' -> 'symbol' Improve readability by renaming the lookup "result" variables to "symbol". Signed-off-by: Josh Poimboeuf <[email protected]>
commit sha 2bfae851eff1189a8e5f7e77ca067a4d4037a552
create-diff-object: refactor dynrela conversion The dynrela (aka .klp.rela) conversion logic is notoriously complex and fragile. Simplify it and improve the comments. This is mainly a cosmetic change. In theory it shouldn't change functionality or break anything. Signed-off-by: Josh Poimboeuf <[email protected]>
push time in 19 days
push eventjpoimboe/kpatch
commit sha 3d6ea904e8b0fa735625d4c59adede6683bc579f
log: include error.h Usage of error() requires error.h
commit sha 6e430624099e736fc4c7aaa508e3572c9f71ad85
kpatch-elf: add livepatch related Elf constants
commit sha 2c3c44fec2d37902d82b09ae6023caecd1f2bebf
kpatch-elf: add kpatch_reindex_elements() and kpatch_rebuild_rela_section_data() Move functions kpatch_reindex_elements() and kpatch_rebuild_rela_section_data() from create-diff-object.c to kpatch-elf.c. These functions will be used to rebuild kpatch elf data in create-klp-module and create-kpatch-module, i.e. during the second "phase" of kpatch-build.
commit sha 91909e92734e2356c07e6b860baf5772b0a0824f
kpatch-elf: ensure SHN_LIVEPATCH syms don't get set to SHN_UNDEF when reindexing elements
commit sha a3108de96aa68d930c9e2a1a4a37acbd47ff43bb
kpatch-elf: fix null dereference when sym->sec is NULL Make sure sym->sec is not NULL before checking for its rela section (sym->sec->rela). This fixes a case where an object may have STT_FUNC symbols whose the sections (sym->sec) were not selected for inclusion (or are located in another object) and hence these symbols do not have sym->sec set. This corner case only recently popped up after reusing kpatch_elf_open() on objects that have been outputted by create-diff-object (and these objects only contain the necessary sections needed for the patch module). This will also automatically exclude livepatch symbols from the check, because they do not have sections associated with them (i.e., sym->sec is NULL). We do not have to check for fentry calls for klp (SHN_LIVEPATCH) symbols, because [1] they do not have sections associated with them, [2] they are not the target functions to be patched, and [3] they are technically just placeholder symbols for symbol resolution in livepatch.
commit sha dac26b8cb2f1b4012ec1018944749c2366267ada
kpatch-elf: for rela sections, find base section by index rather than name If there exist multiple sections with the same name (which can happen when using the --unique option with ld, which will be used to keep multiple (per-object) .parainstructions and .altinstructions sections separate), find_section_by_name() will only return the first section name match, which leads to incorrect base section assignments for rela sections. Fix this by using the sh_info field of the rela section to find its base section instead, which contains the index of the section to which the relocation applies.
commit sha 52e2ad66cae900a18fdbd7540a7e8751c7262f69
kpatch-elf: add kpatch_remove_and_free_section() Add kpatch_remove_and_free_section(), which, given a section name, removes and frees all matching sections from the passed in kpatch_elf.
commit sha b6a15f3dd6bbf85bcff8691115f0249a6f6a2d99
create-diff-object: rename 'name' variable to 'objname' 'name' isn't very descriptive, rename it to 'objname' to avoid confusion
commit sha 58de46cb9e5357405c9fb731b1ed15aff408c4df
lookup: parse Module.symvers in lookup_open() Have lookup_open() also parse Module.symvers and add the resulting symbols and their objnames to the lookup table. This code was essentially cherry-picked from Josh Poimboeuf's lookup code found here: https://github.com/jpoimboe/kpatch/commit/8cdca59c8844505bcf40b59b5c5050b03e974fea That patch was modified to fix a bug in obj_read() (calling elf_end() without strdup'ing the symbol name strings, which was causing null dereferences) and to fix up the module name after reading it from Module.symvers (replacing '-' with '_' and stripping the path prefixes). Also, add lookup_exported_symbol_objname(), which looks up the objname of an exported symbol by making use of the objname information obtained from Module.symvers.
commit sha 87643703a75746e03c6942f7ecc722113fa21783
create-diff-object: create .kpatch.relocations and .kpatch.symbols sections Instead of creating dynrela sections, have create-diff-object create intermediate sections .kpatch.relocations and .kpatch.symbols which can then be used to build (depending on kernel version) either dynrela sections or klp rela/klp arch sections + klp symbols in a later phase of kpatch-build.
commit sha 42902d0fccd8a4889b5923aeff622681851ad68c
create-diff-object: create intermediate .kpatch.arch section In addition to .kpatch.relocations and .kpatch.symbols, have create-diff-object create an .kpatch.arch section. This section can be used to create .klp.arch. sections that are required for klp modules built for versions >= 4.9. Each entry in the .kpatch.arch section represents an arch-specific section (.altinstructions or .parainstructions) and contains a pointer to the arch-specific section itself (see kpatch_arch struct member 'sec') and a pointer to the objname string (see kpatch_arch struct member 'objname'). This is enough information to be able to build .klp.arch. sections in a later phase of kpatch-build.
commit sha 900d28fe752396154da038356c95126d048223de
kpatch-elf: add find_rela_by_offset() Add find_rela_by_offset(), which, given a relocation section and offset, will return the rela struct with the matching offset.
commit sha 09d2af5cb44417a89066b44360b774133df6e232
create-klp-module: add new program that creates patch modules that have klp elements Add a new program, create-klp-module, that, given a built module (.ko), will create a patch module with klp rela sections, klp arch sections, and klp symbols.
commit sha 0cc693ba36ac0f8292926bb7d912ef2b74fe33dc
create-kpatch-module: add new program that creates kpatch modules Add new program create-kpatch-module, that, given an intermediate object outputted by create-diff-object, outputs an object (.o) that contains the .kpatch.dynrelas section required by kpatch.
commit sha 355996e366c0adc78faf12846dbe8241f0c39dd5
livepatch-patch-hook: ensure compatibility with kernels < 4.7 and >= 4.7 Use dynrelas when kernel version is < 4.7 and klp relas otherwise.
commit sha b1cdc83d574d3eaa01d47f1649cc91829b8e2b79
kpatch-build: build dynrelas or klp relas depending on kernel version Introduce a second phase in the kpatch-build process that creates kpatch modules or livepatch modules that use the new klp rela sections depending on the kernel version being worked on. This change uses the two new programs to either create a patch module that uses dynrelas (create-kpatch-module) or a patch module that uses klp rela and arch sections + klp symbols marked with the correct Elf flags (create-klp-module). For klp patch modules, the --unique flag for ld is needed to prevent .parainstructions and .altinstructions sections from different objects from being merged, as arch_klp_init_object_loaded() applies these sections per-object.
commit sha ac899455ab750fefb0f1aabed548f74c1580b841
create-diff-object: convert global symbols to local As reported in PR #658, when patching an exported function which is used by the patch module init code, the init code will incorrectly link to the patched version of the function and will call the patched function before its relocations have been applied. For example, when patching __kmalloc(), I see: # insmod kpatch-kmalloc.ko kpatch_kmalloc: module is marked as livepatch module, but livepatch support is disabled kernel tried to execute NX-protected page - exploit attempt? (uid: 0) BUG: unable to handle kernel paging request at ffffc90001d03c58 IP: 0xffffc90001d03c58 PGD 7c8b4067 PUD 7c8b5067 PMD 755f7067 PTE 800000007ad03163 Oops: 0011 [#1] PREEMPT SMP Modules linked in: kpatch_kmalloc(OE+) kpatch(OE) ip6t_rpfilter ip6t_REJECT nf_reject_ipv6 xt_conntrack cfg80211 rfkill ebtable_nat ebtable_broute bridge stp llc ebtable_filter ebtables ip6table_nat nf_conntrack_ipv6 nf_defrag_ipv6 nf_nat_ipv6 ip6table_mangle ip6table_security ip6table_raw ip6table_filter ip6_tables iptable_nat nf_conntrack_ipv4 nf_defrag_ipv4 nf_nat_ipv4 nf_nat nf_conntrack iptable_mangle iptable_security iptable_raw snd_hda_codec_generic ppdev crct10dif_pclmul crc32_pclmul crc32c_intel ghash_clmulni_intel snd_hda_intel virtio_balloon snd_hda_codec snd_hwdep serio_raw virtio_console snd_hda_core parport_pc parport snd_pcm virtio_net snd_timer snd i2c_piix4 soundcore virtio_blk qxl drm_kms_helper ttm drm virtio_pci virtio_ring virtio ata_generic pata_acpi CPU: 1 PID: 1042 Comm: insmod Tainted: G OE 4.10.0-rc5 #1 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.9.1-1.fc24 04/01/2014 task: ffff88007560d480 task.stack: ffffc90001d00000 RIP: 0010:0xffffc90001d03c58 RSP: 0018:ffffc90001d03c50 EFLAGS: 00010286 RAX: 0000000000000004 RBX: 0000000000000008 RCX: 0000000000000000 RDX: 0000000000000000 RSI: 00000000014080c0 RDI: 0000000000000008 RBP: ffff88007ad00058 R08: 0000000000000001 R09: 0000000000000001 R10: 0000000000000000 R11: 0000000000000001 R12: 00000000fffffff4 R13: ffffffffa0394ef0 R14: 0000000000000000 R15: ffffc90001d03ea8 FS: 00007f9689d74700(0000) GS:ffff88007d000000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: ffffc90001d03c58 CR3: 000000007af1d000 CR4: 00000000001406e0 Call Trace: ? kzalloc.constprop.6+0xe/0x10 [kpatch_kmalloc] ? patch_init+0xa6/0x1000 [kpatch_kmalloc] ? 0xffffffffa0399000 ? do_one_initcall+0x52/0x1b0 ? do_init_module+0x27/0x1fa ? rcu_read_lock_sched_held+0x4a/0x80 ? kmem_cache_alloc_trace+0x28a/0x2f0 ? do_init_module+0x5f/0x1fa ? load_module+0x2446/0x2b90 ? __symbol_put+0x90/0x90 ? vfs_read+0x137/0x180 ? SYSC_finit_module+0xdf/0x110 ? SyS_finit_module+0xe/0x10 ? entry_SYSCALL_64_fastpath+0x1f/0xc2 Code: c9 ff ff 10 00 00 00 00 00 00 00 86 02 01 00 00 00 00 00 50 3c d0 01 00 c9 ff ff 18 00 00 00 00 00 00 00 b4 33 39 a0 ff ff ff ff <a0> 3c d0 01 00 c9 ff ff a6 90 39 a0 ff ff ff ff 00 00 00 00 00 RIP: 0xffffc90001d03c58 RSP: ffffc90001d03c50 CR2: ffffc90001d03c58
commit sha d4f9da349434729bf84643ec33396630fe893b65
Merge pull request #661 from jpoimboe/convert-global-to-local create-diff-object: convert global symbols to local
commit sha 43f8683cd721127f186206181cc01b458a4866a5
kpatch-build: rename kpatch-tmp.ko to tmp.ko Rename kpatch-tmp.ko to tmp.ko, since create-klp-module will run into issues if we happen to have a patch named tmp.patch
commit sha b0f5ded2b0bc1f58efc00a130eea633f04a2ad63
kpatch-intermediate.h: fix comments
push time in 20 days
pull request commentdynup/kpatch
create-diff-object: process debug sections last
This was found via code inspection, so I don't really have a unit test for it.
comment created time in 20 days
PR opened dynup/kpatch
Process the debug sections only after all the other inclusion logic has finished, since it makes decisions based on what else has already been included.
Signed-off-by: Josh Poimboeuf [email protected]
pr created time in 20 days
pull request commentdynup/kpatch
A unit test (or tests) for this PR would be good too.
comment created time in 20 days
Pull request review commentdynup/kpatch
static void kpatch_bundle_symbols(struct kpatch_elf *kelf) } } +static void kpatch_add_child_symbol(struct symbol *parent, struct symbol *child)+{+ parent->nb_children++;+ parent->children = realloc(parent->children,+ sizeof(*parent->children) * parent->nb_children);+ if (!parent->children)+ ERROR("failed to add child %s to symbol %s", child->name,+ parent->name);+ child->parent = parent;+ parent->children[parent->nb_children - 1] = child;+}+
Instead of a dynamic array, how about a linked list? That's what the rest of the code does and I think it would be a little cleaner.
comment created time in 20 days
Pull request review commentdynup/kpatch
static void kpatch_mark_ignored_sections_same(struct kpatch_elf *kelf) sym->status = SAME; } +static void kpatch_mark_ignored_children_same(struct symbol *sym)+{+ int i;++ for (i = 0; i < sym->nb_children; ++i) {+ sym->children[i]->status = SAME;+ kpatch_mark_ignored_children_same(sym->children[i]);
Why? Can there be grandchildren?
comment created time in 20 days
Pull request review commentdynup/kpatch
static int kpatch_line_macro_change_only(struct section *sec) } #endif +static bool kpatch_changed_child_needs_parent_profiling(struct symbol *sym)+{+ int i;++ for (i = 0; i < sym->nb_children; i++) {+ if (sym->children[i]->has_func_profiling)+ continue;+ if (sym->children[i]->sec->status == CHANGED ||+ kpatch_changed_child_needs_parent_profiling(sym->children[i]))+ return true;
Why the recursive call? Isn't the for loop already doing this check for all the siblings?
comment created time in 20 days
Pull request review commentdynup/kpatch
static void kpatch_detect_child_functions(struct kpatch_elf *kelf) struct symbol *sym; list_for_each_entry(sym, &kelf->symbols, list) {- char *coldstr;+ struct symbol *parent;+ char *childstr;+ char *pname; - coldstr = strstr(sym->name, ".cold.");- if (coldstr != NULL) {- char *pname;+ if (sym->type != STT_FUNC)+ continue; - pname = strndup(sym->name, coldstr - sym->name);- if (!pname)- ERROR("strndup");+ childstr = strstr(sym->name, ".cold.");+ if (!childstr) {+ childstr = strstr(sym->name, ".part.");+ if (!childstr)+ continue;+ } - sym->parent = find_symbol_by_name(&kelf->symbols, pname);- free(pname);+ pname = strndup(sym->name, childstr - sym->name);+ if (!pname)+ ERROR("strndup"); - if (!sym->parent)- ERROR("failed to find parent function for %s", sym->name);+ parent = find_symbol_by_name(&kelf->symbols, pname);+ free(pname); - sym->parent->child = sym;+ if (!parent) {+ /* ".part." symbols don't always have parents */+ if (sym->has_func_profiling)+ continue;+ ERROR("failed to find parent function for %s",+ sym->name);
Is this really an error? Not every ".part." function has a parent and not every function has func profiling, so presumably not every ".part" function has func profiling?
comment created time in 20 days
Pull request review commentdynup/kpatch
static int kpatch_line_macro_change_only(struct section *sec) } #endif +static bool kpatch_changed_child_needs_parent_profiling(struct symbol *sym)
It might be helpful to add a comment somewhere explaining that .cold children don't have fentry but that .part children often do.
BTW, the terms 'parent' and 'child' in this context have always bothered me because they're so ambigious. What do you think? Any ideas for better naming? Superfunction/subfunction?
comment created time in 20 days
pull request commentdynup/kpatch
kpatch-build: Make local static twining stricter
Thanks. We want the unit tests to be as comprehensive as possible. I think some overlap between unit tests and integration tests is ok.
comment created time in 20 days
pull request commentdynup/kpatch
kpatch-build: Make local static twining stricter
Looks good. Would it be possible to create a unit test for this one?
comment created time in 20 days
pull request commentdynup/kpatch
@julien-thierry once the test PR is merged, you can rebase this PR to update the test/unit/objs ref to reference the new test PR. Then feel free to merge this one.
comment created time in 21 days
pull request commentdynup/kpatch-unit-test-objs
Add test for mangled symbol modification
And with that change, feel free to merge this PR.
comment created time in 21 days
pull request commentdynup/kpatch-unit-test-objs
Add test for mangled symbol modification
@julien-thierry for newer unit tests we've also been including the issue name in the file name. In this case I don't think there's an issue opened for it, but you can instead use the pr #. So maybe mangled-symbol-modification-issue-1048.
comment created time in 21 days
push eventjpoimboe/kpatch
commit sha 21d2f3803fb1835b14834c47949b4fbcfc35e638
fix
push time in 22 days
push eventjpoimboe/kpatch
commit sha 0ef451214f825317e8a4fbe15a401ca2a960705e
fix
push time in 22 days
push eventjpoimboe/kpatch
commit sha e59355c2b74375bbc29b8991abc1d427b40d89e3
test/integration: Make multiple.test cleanup after itself If an error occurs while loading a module or one of the tests, multiple.test will exit leaving the working modules loaded. This leaves the system in an unwanted state and causes the test that previously pass to fail (succeeding before being loaded for multiple.test's point of view). Cleanup the loaded modules before exiting due to errors. Also take this opportunity to factorize the test for the different distros. Signed-off-by: Julien Thierry <[email protected]>
commit sha 58eead5a16fa557d966820040c2ffc5b3ce3b7a5
kpatch: Fix all module unloading Some versions of Linux livepatching require patches to be unloaded in the opposite order than the order they were loaded. Currently kpatch simply goes through the list of sysfs livepatch directories and tries to disable them one by one. This makes the following fail: $ kpatch load a.ko $ kpatch load b.ko $ kpatch unload --all kpatch: failed to unload module b Since kpatch is not bound to a version of Linux, cater for those version that do not support random unloading order, even for patches that do not depend on one another. Signed-off-by: Julien Thierry <[email protected]>
commit sha c9a4e09b459772e250ce03c53fbb2628aa617fe9
test/integration: Fix kpatch-test module unloading The unload_all() function in kpatch-test script is out dated and does not unload patches loaded through livepatching. Luckily, "kpatch unload --all" should support both kpatch unloading kpatch patches and livepatch patches. Signed-off-by: Julien Thierry <[email protected]>
commit sha a02842fb693b92e943a8bfad55b676646dfd3c05
kpatch-elf: Free sections in elf teardown Currently, only rela section get freed. This seems like a simple scope mistake. Free all sections regardless of their nature in kpatch_elf_teardown() Signed-off-by: Julien Thierry <[email protected]>
commit sha 3a1a73f08cdb4f13e010e220f26c408d8b5125d1
Make symvers reading code more flexible. Kernel commit cb9b55d21fe0 modpost: add support for symbol namespaces adds a new namespace column to Module.symvers file which can be blank. fscanf is no longer a viable solution to parse that. Switch to the way scripts/mod/modpost.c handles this and try to support both versions with and without namespace column. Signed-off-by: Artem Savkov <[email protected]>
commit sha eec99f0923869a0046fa7bdb2dc328aa89c3bc69
Merge pull request #1046 from julien-thierry/unload-fixes Unload fixes
commit sha c9519b6a1411e06117ffd476502a8d2d0b799bda
Merge pull request #1050 from julien-thierry/elf-teardown-free-sec kpatch-elf: Free sections in elf teardown
commit sha e0bd024c18f1273cd5617cd37aad4e110145943f
Merge pull request #1052 from sm00th/symvers Make symvers reading code more flexible.
commit sha 5eac3184e5e1c2d8ca6ae1ac7f84c7d916bbcb89
create-diff-object: update dynrela and toc_rela comments These are complicated topics. Try to clarify the comments as much as possible. Signed-off-by: Josh Poimboeuf <[email protected]>
commit sha 330541d08eb4e37024ec0193f7aa5149898043aa
create-diff-object: refactor may_need_dynrela() To make the code clearer, move more of the dynrela decision making to earlier, in may_need_dynrela(). Ideally we could make all the decisions in may_need_dynrela(), and then rename it to need_dynrela(), but this is a good start. The rest of the decisions are dependent on the lookup table. Signed-off-by: Josh Poimboeuf <[email protected]>
commit sha bbae0324d7f8e7bce904581953a23ae6c2497d1c
create-diff-object: process debug sections last Process the debug sections only after all the other inclusion logic has finished, since it makes decisions based on what else has already been included. Signed-off-by: Josh Poimboeuf <[email protected]>
commit sha e8034843854b0f2f76ca08587023ac9314ffe307
create-diff-object: reduce indentation in kpatch_create_patches_sections() Reverse the if condition and use a 'continue' statement to reduce indentation and improve readability. Signed-off-by: Josh Poimboeuf <[email protected]>
commit sha 5433fc279c98082737a67c417dfde52f9667d3ef
lookup: remove unused testing code This testing code is no longer used. Remove it. Signed-off-by: Josh Poimboeuf <[email protected]>
commit sha 2022440d3fd566bd91a943089e1e6343cc0221b0
lookup: rename 'value' -> 'addr' Rename 'value' to 'addr' to more accurately describe it. Signed-off-by: Josh Poimboeuf <[email protected]>
commit sha 89952d6bb46b640fa3f0d3e9ef998237b51a60c4
lookup: rename 'pos' to 'sympos' To more accurately describe its purpose. Signed-off-by: Josh Poimboeuf <[email protected]>
commit sha 2a63bec03dbfaf90332a9ff5dea9d8c4a3bc80c9
lookup: convert lookup functions to return bool The code is easier to follow if these functions return bool. Signed-off-by: Josh Poimboeuf <[email protected]>
commit sha 412d8aec481e90b9624810379cb915077259cc4f
todo
commit sha 1e587bc4660681b2c03f9cd7088c437df3f91f63
todo
commit sha c935b2ab1676719aa4c6050d2a30249f5d4a5f56
rewrite dynrela logic
commit sha dedd63542a458c9f3077b7fae9c0d9a98eaca317
fixes
push time in 22 days
push eventjpoimboe/kpatch
commit sha d6874d2e7f0710b53c5a7b5b7fc0cea33186121b
fixes
commit sha bfc7ed192dc876c2a6871e1df8b44b41526c50c2
remove .klp.arch sections
commit sha a0505d958901828d065d9fbce21aa13ff260b26f
allow jump tables, enforce rules
push time in 22 days
push eventjpoimboe/kpatch
commit sha e790d59bec1a03170f371d0ba0e14cb54a814941
create-diff-object: name arguments Use named variables instead of cmdline argument indexes so that it is easier to read create-diff-object.c. Signed-off-by: Josh Poimboeuf <[email protected]> Signed-off-by: Artem Savkov <[email protected]>
commit sha 3aa5abb8072c2e198a3e5dbb84502823d830b8cc
kpatch-build: use symbol table instead of kobject create-diff-object doesn't really need the full kernel object file as input. All it requires is a symbol table. Switch to using "eu-readelf -s"'s output instead of object files. This will enable us to cover more cases in unit tests. Signed-off-by: Josh Poimboeuf <[email protected]> Signed-off-by: Artem Savkov <[email protected]>
commit sha de10550faeec030366d240e4035a871ea345fa9f
create-klp-module: group .kpatch.symbols with like-scope From Oracle's Linker and Libraries Guide [1]: "The symbols in a symbol table are written in the following order ... The global symbols immediately follow the local symbols in the symbol table. The first global symbol is identified by the symbol table sh_info value. Local and global symbols are always kept separate in this manner, and cannot be mixed together." [1] https://docs.oracle.com/cd/E19120-01/open.solaris/819-0690/chapter6-79797/index.html Fixes #854. Signed-off-by: Joe Lawrence <[email protected]>
commit sha a3ee36944811278f06ce26df71a7609fd2a3a9a5
livepatch-patch-hook: add RHEL immediate check The 'immediate' flag removal is going to be backported to RHEL 7. Adjust the check accordingly. Signed-off-by: Josh Poimboeuf <[email protected]>
commit sha 8927b575097342100c2622489b3d2ce5a079247e
create-diff-object: ignore .cold.* suffixes in is_bundleable() While building a gcc-consprop patch from integration tests gcc8 would place a __timekeeping_inject_sleeptime.constprop.18.cold.27 symbol into .text.unlikely.__timekeeping_inject_sleeptime.constprop.18 section. Because section name doesn't have the '.cold.27' suffix this symbol fails is_bundleable() check while still being bundleable and later exits early in kpatch_rename_mangled_functions() without renaming the corresponding patched function. All of this results in a create-diff-object errror: ERROR: timekeeping.o: symbol changed sections: __timekeeping_inject_sleeptime.constprop.18.cold.27 /home/asavkov/dev/kpatch/kpatch-build/create-diff-object: unreconcilable difference Fix by ignoring .cold.* name suffix in is_bundleable() for.text.unlikely sections. Signed-off-by: Artem Savkov <[email protected]>
commit sha 7023c239b15247e299e86744e217d4474768ca14
create-diff-object: don't convert .TOC. references to dynrelas When I made a patch to the nfsd module on a ppc64le system with a RHEL 7 based kernel, livepatch prevented the target module from loading with: livepatch: symbol '.TOC.' not found in symbol table References to this symbol are treated specially by the kernel module loader, so references to it should never be converted to dynrelas. Signed-off-by: Josh Poimboeuf <[email protected]>
commit sha 3ba9a145e9a2ad30b9f579c13850d6f0c085e91f
gcc-plugin: Include additional header for GCC 8 plugin compilation fails on GCC 8: In file included from gcc-plugins/gcc-common.h:100, from gcc-plugins/ppc64le-plugin.c:1: /usr/lib/gcc/powerpc64le-linux-gnu/8/plugin/include/attribs.h: In function ‘tree_node* canonicalize_attr_name(tree)’: /usr/lib/gcc/powerpc64le-linux-gnu/8/plugin/include/attribs.h:118:11: error: ‘get_identifier_with_length’ was not declared in this scope return get_identifier_with_length (s + 2, l - 4); ^~~~~~~~~~~~~~~~~~~~~~~~~~ /usr/lib/gcc/powerpc64le-linux-gnu/8/plugin/include/attribs.h:118:11: note: suggested alternative: ‘get_attr_min_length’ return get_identifier_with_length (s + 2, l - 4); ^~~~~~~~~~~~~~~~~~~~~~~~~~ get_attr_min_length Makefile:34: recipe for target 'gcc-plugins/ppc64le-plugin.so' failed get_identifier_with_length() is defined under stringpool.h, include this header file for GCC 8, before including attribs.h Signed-off-by: Kamalesh Babulal <[email protected]>
commit sha c2f6d4d0fb21bf855bfbaf29c3d109cb8c59e63c
Merge pull request #860 from jpoimboe/rhel-immediate livepatch-patch-hook: add RHEL immediate check
commit sha 5736f18d83c87579e94e5ff2dafc85a521280b9d
test/unit: run submodule command from base git directory This fixes the following error with an older version of git (1.8.3.1): make -C test/unit make[1]: Entering directory `/root/kpatch/test/unit' git submodule update --init --rebase You need to run this command from the toplevel of the working tree. Signed-off-by: Josh Poimboeuf <[email protected]>
commit sha 019c02983009ce418ee525b7665634c068c60e49
Add .cold. to mangled functions check gcc8 introduces ".cold." optimization symbols that have arbitrary trainling numbers in their names just like ".isra." and others. Add ".cold." to a condition in kpatch_rename_mangled_functions() Signed-off-by: Artem Savkov <[email protected]>
commit sha b387dffab6f6f0a84a60c36e9540938a18f4140e
Merge pull request #863 from jpoimboe/unit-submodule-root-dir test/unit: run submodule command from base git directory
commit sha 9d0a2105ef5c53bfce2720e1066abd1feb8b2b92
Merge pull request #861 from kamalesh-babulal/gcc_plugin gcc-plugin: Include additional header for GCC 8
commit sha a879d1f3ea0f5783fde4c1af2fa9bb1264b41ce3
Merge pull request #859 from jpoimboe/ppc-TOC create-diff-object: don't convert .TOC. references to dynrelas
commit sha ace1e2cbf603ce028112069ba0df64cdba92f61d
Merge pull request #849 from sm00th/cdo-symtab create-diff-object symtab
commit sha 27accf46ee26a81e4ebae94a9d8121adcd535bb4
Merge pull request #857 from joe-lawrence/local-symbols create-klp-module: group .kpatch.symbols with like-scope
commit sha 355927287d87de14bcb30fc35cf73c95ff63c08a
livepatch-patch-hook: fix non-rhel builds Preprocessor doesn't stop unwinding macroses in #if clauses if one of the conditions is false resulting in the following error when trying to build on non-rhel system: patch/livepatch-patch-hook.c:53:48: error: missing binary operator before token "(" RHEL_RELEASE_CODE <= RHEL_RELEASE_VERSION(7, 5)) Fix by using 2 levels of #ifs instead of &&. The same way HAVE_CALLBACKS does. Signed-off-by: Artem Savkov <[email protected]>
commit sha 6c58f09cc759972f66623942081b371a63586073
test/unit: update objects to include cold testcase Update unit test objects subrepo to include x86_64 gcc-constprop-cold testcase. Signed-off-by: Artem Savkov <[email protected]>
commit sha a7c413d4e97fce8cab8efaf99e1b58792138442f
Merge pull request #856 from sm00th/unlikely-cold create-diff-object: ignore .cold.* suffixes in is_bundleable()
commit sha 74392002de84f048ce5bf7afab6180d800bdbdfc
Merge pull request #864 from sm00th/rhel-immediate-fix livepatch-patch-hook: fix non-rhel builds
commit sha 7646c68b595e52c1c2dac272bc30b9cfc031f656
testing: kpatch-build should set all module names Since c0105ea46774 ("kpatch-build: set default module prefix accordingly") kpatch-build has automatically named resulting patch modules with a "kpatch-" or "livepatch-" prefix (depending on its type). To avoid naming confusion, have kpatch-test name all of its patch modules with a "test-" prefix. Fixes #867. Signed-off-by: Joe Lawrence <[email protected]>
push time in 22 days
Pull request review commentdynup/kpatch
static void kpatch_correlate_static_local_variables(struct kpatch_elf *base, ERROR("sections %s and %s aren't correlated for symbol %s", sym->sec->name, patched_sym->sec->name, sym->name); - log_debug("renaming and correlating static local %s to %s\n",- patched_sym->name, sym->name);-- patched_sym->name = strdup(sym->name);- sym->twin = patched_sym;- patched_sym->twin = sym;-- /* set initial status, might change */- sym->status = patched_sym->status = SAME;+ kpatch_correlate_static_local(sym, patched_sym); if (bundled) {- sym->sec->twin = patched_sym->sec;- patched_sym->sec->twin = sym->sec;+ kpatch_correlate_section(sym->sec, patched_sym->sec);+ kpatch_correlate_symbol(sym->sec->secsym, patched_sym->sec->secsym); - sym->sec->secsym->twin = patched_sym->sec->secsym;- patched_sym->sec->secsym->twin = sym->sec->secsym;-- if (sym->sec->rela && patched_sym->sec->rela) {- sym->sec->rela->twin = patched_sym->sec->rela;- patched_sym->sec->rela->twin = sym->sec->rela;- }+ if (sym->sec->rela && patched_sym->sec->rela)+ kpatch_correlate_section(sym->sec->rela, patched_sym->sec->rela);
This is all quite similar to what kpatch_process_section_correlation() does... could it all be replaced with
if (bundled) {
kpatch_correlate_section(sym->sec, patched_sym->sec);
kpatch_process_section_correlation(sym->sec);
}
?
And for that matter I wonder if it would be better to have kpatch_correlate_section() automatically do all the work in kpatch_process_section_correlation()? Then kpatch_correlate_section() could call a lower-level __kpatch_correlate_section() version which doesn't do that extra work. So kpatch_correlate_section() would be a higher-level interface which just does the right thing, and then this could just be
if (bundled)
kpatch_correlate_section(sym->sec, patched_sym->sec);
And similarly kpatch_correlate_sections() wouldn't need to call kpatch_process_section_correlation().
comment created time in 23 days
issue commentdynup/kpatch
Static Local Variable: missing reference to it...
I'm working on improving jump label / static key support this week, I suspect it will solve this problem.
comment created time in 24 days
push eventdynup/kpatch
commit sha 3a1a73f08cdb4f13e010e220f26c408d8b5125d1
Make symvers reading code more flexible. Kernel commit cb9b55d21fe0 modpost: add support for symbol namespaces adds a new namespace column to Module.symvers file which can be blank. fscanf is no longer a viable solution to parse that. Switch to the way scripts/mod/modpost.c handles this and try to support both versions with and without namespace column. Signed-off-by: Artem Savkov <[email protected]>
commit sha e0bd024c18f1273cd5617cd37aad4e110145943f
Merge pull request #1052 from sm00th/symvers Make symvers reading code more flexible.
push time in 24 days
PR merged dynup/kpatch
Kernel commit cb9b55d21fe0 modpost: add support for symbol namespaces adds a new namespace column to Module.symvers file which can be blank. fscanf is no longer a viable solution to parse that. Switch to the way scripts/mod/modpost.c handles this and try to support both versions with and without namespace column.
pr closed time in 24 days
push eventdynup/kpatch
commit sha a02842fb693b92e943a8bfad55b676646dfd3c05
kpatch-elf: Free sections in elf teardown Currently, only rela section get freed. This seems like a simple scope mistake. Free all sections regardless of their nature in kpatch_elf_teardown() Signed-off-by: Julien Thierry <[email protected]>
commit sha c9519b6a1411e06117ffd476502a8d2d0b799bda
Merge pull request #1050 from julien-thierry/elf-teardown-free-sec kpatch-elf: Free sections in elf teardown
push time in 24 days
PR merged dynup/kpatch
Currently, only rela section get freed. This seems like a simple scope mistake.
Free all sections regardless of their nature in kpatch_elf_teardown()
Signed-off-by: Julien Thierry [email protected]
pr closed time in 24 days
Pull request review commentdynup/kpatch
static void kpatch_correlate_static_local_variables(struct kpatch_elf *base, ERROR("sections %s and %s aren't correlated for symbol %s", sym->sec->name, patched_sym->sec->name, sym->name); - log_debug("renaming and correlating static local %s to %s\n",- patched_sym->name, sym->name);-- patched_sym->name = strdup(sym->name);- sym->twin = patched_sym;- patched_sym->twin = sym;+ CORRELATE_ELEMENTS(sym, patched_sym, "static local");
Here you might as well call a kpatch_correlate_static_local_variable() wrapper which hides the ugly macro, similar to the other two helpers.
comment created time in 24 days
Pull request review commentdynup/kpatch
static void kpatch_correlate_static_local_variables(struct kpatch_elf *base, ERROR("sections %s and %s aren't correlated for symbol %s", sym->sec->name, patched_sym->sec->name, sym->name); - log_debug("renaming and correlating static local %s to %s\n",- patched_sym->name, sym->name);-- patched_sym->name = strdup(sym->name);- sym->twin = patched_sym;- patched_sym->twin = sym;+ CORRELATE_ELEMENTS(sym, patched_sym, "static local"); /* set initial status, might change */ sym->status = patched_sym->status = SAME;
I think this is no longer needed since CORRELATE_ELEMENTS does this?
comment created time in 24 days
Pull request review commentdynup/kpatch
static void kpatch_compare_symbols(struct list_head *symlist) } } +#define CORRELATE_ELEMENTS(_e1_, _e2_, kindstr) \+do { \+ typeof(_e1_) e1 = (_e1_); \+ typeof(_e2_) e2 = (_e2_); \+ e1->twin = e2; \+ e2->twin = e1; \+ /* set initial status, might change */ \+ e1->status = e2->status = SAME; \+ if (strcmp(e1->name, e2->name)) { \+ /* Rename mangled element */ \+ log_debug("renaming %s %s to %s\n", \+ kindstr, e2->name, e1->name); \+ e2->name = strdup(e1->name); \+ } \+} while (0)++#define UNCORRELATE_ELEMENT(_elem_) \+do { \+ typeof(_elem_) elem = (_elem_); \+ if (elem->twin->orig_name != elem->twin->name) { \+ free(elem->twin->name); \+ elem->twin->name = elem->twin->orig_name; \+ } \+ elem->twin->twin = NULL; \+ elem->twin = NULL; \+ if (elem->orig_name != elem->name) { \+ free(elem->name); \+ elem->name = elem->orig_name; \+ } \+} while (0)++static void make_correlated_sections(struct section *sec1, struct section *sec2)+{+ CORRELATE_ELEMENTS(sec1, sec2, "section");+}++static void make_correlated_symbols(struct symbol *sym1, struct symbol *sym2)+{+ CORRELATE_ELEMENTS(sym1, sym2, "symbol");+}
Naming suggestions: make_correlated_sections() almost makes it sound like it's creating a section - how about renaming to kpatch_correlate_section()? That also gives it a name analagous to its caller kpatch_correlate_sections(). And a similar comment for make_correlated_symbols().
And that would also imply a CORRELATE_ELEMENTS -> CORRELATE_ELEMENT rename for consistency - yes, it's correlating two elements, but depending on one's perspective they might be considered the same element :-)
comment created time in 24 days
push eventdynup/kpatch
commit sha e59355c2b74375bbc29b8991abc1d427b40d89e3
test/integration: Make multiple.test cleanup after itself If an error occurs while loading a module or one of the tests, multiple.test will exit leaving the working modules loaded. This leaves the system in an unwanted state and causes the test that previously pass to fail (succeeding before being loaded for multiple.test's point of view). Cleanup the loaded modules before exiting due to errors. Also take this opportunity to factorize the test for the different distros. Signed-off-by: Julien Thierry <[email protected]>
commit sha 58eead5a16fa557d966820040c2ffc5b3ce3b7a5
kpatch: Fix all module unloading Some versions of Linux livepatching require patches to be unloaded in the opposite order than the order they were loaded. Currently kpatch simply goes through the list of sysfs livepatch directories and tries to disable them one by one. This makes the following fail: $ kpatch load a.ko $ kpatch load b.ko $ kpatch unload --all kpatch: failed to unload module b Since kpatch is not bound to a version of Linux, cater for those version that do not support random unloading order, even for patches that do not depend on one another. Signed-off-by: Julien Thierry <[email protected]>
commit sha c9a4e09b459772e250ce03c53fbb2628aa617fe9
test/integration: Fix kpatch-test module unloading The unload_all() function in kpatch-test script is out dated and does not unload patches loaded through livepatching. Luckily, "kpatch unload --all" should support both kpatch unloading kpatch patches and livepatch patches. Signed-off-by: Julien Thierry <[email protected]>
commit sha eec99f0923869a0046fa7bdb2dc328aa89c3bc69
Merge pull request #1046 from julien-thierry/unload-fixes Unload fixes
push time in 24 days
PR merged dynup/kpatch
Couple of fixes for missing/failing module unloading found while running kpatch testsuite.
pr closed time in 24 days
Pull request review commentdynup/kpatch
correleating constprop subfunctions created by the optimization: ``` The current workaround for this issue to add `__attribute__((noclone))` to offending functions.++Sibling calls+-------------++If function A() calls function B() at the end of A() and both return similar+data-types, GCC may deem them "sibling calls" and apply a tail call+optimization in which A() restores the stack to is callee state before setting+up B()'s arguments and jumping to B().++This may be an issue for kpatches on PowerPC which modify only A() or B() and+the function call crosses a kernel module boundary: the sibling call+optimization has changed expected calling conventions and (un)patched code may+not be similarly modified.++Commit [8b952bd77130](https://github.com/dynup/kpatch/commit/8b952bd77130)+("create-diff-object/ppc64le: Don't allow sibling calls") contains an+excellent example and description of this problem with annotated disassembly.++Adding `__attribute__((optimize("-fno-optimize-sibling-calls")))` instructs+GCC to turn off the optimization for the given function.
Reading this, it's not clear how the user should know they've hit this issue in the first place. It should probably mention the error message:
ERROR("Found an unsupported sibling call at %s()+0x%lx. Add __attribute__((optimize(\"-fno-optimize-sibling-calls\"))) to %s() definition.",
comment created time in 24 days
Pull request review commentdynup/kpatch
if (static_key_true(&key1)) /* supported */ if (static_key_enabled(&key1)) ```++Constant propagation symbol changes+-----------------------------------++GCC's constant propagation optimizations may result in kpatch-build+errors like: `ERROR: timekeeping.o: symbol changed sections: .text.timekeeping_update.constprop.9`++This is currently tracked as issue+[#935](https://github.com/dynup/kpatch/issues/935) "duplicate" mangled+fuctions. In that case, readelf revealed that kpatch-build wasn't+correleating constprop subfunctions created by the optimization:+```+# eu-readelf -s orig/kernel/time/timekeeping.o | grep timekeeping_update+ 137: 0000000000000000 552 FUNC LOCAL DEFAULT 48 timekeeping_update.constprop.9+ 138: 0000000000000000 568 FUNC LOCAL DEFAULT 50 timekeeping_update.constprop.8+# eu-readelf -s patched/kernel/time/timekeeping.o | grep timekeeping_update+ 137: 0000000000000000 552 FUNC LOCAL DEFAULT 48 timekeeping_update.constprop.10+ 138: 0000000000000000 568 FUNC LOCAL DEFAULT 50 timekeeping_update.constprop.9+```+The current workaround for this issue to add `__attribute__((noclone))`+to offending functions.
I think this issue was fixed in #1043. Should this commit be dropped?
comment created time in 24 days
PR closed dynup/kpatch
Add the __mcount_loc section on ppc64le. It has pointers to all the mcount calls. This will enable the ftrace hook to be used for patched functions.
We have also been seeing a mysterious ppc64le livepatch bug where r2 (TOC pointer) gets intermittently corrupted. My only theory is that the call to _mcount is doing that somehow. Now that call will be replaced with a NOP when the patch module is loaded.
Signed-off-by: Josh Poimboeuf [email protected]
pr closed time in 24 days
issue commentdynup/kpatch
Not to say that we shouldn't do it, just that we should be cautious in deciding to do it.
comment created time in 2 months
issue commentdynup/kpatch
* An "effective kernel version" may be confusing to a user if it only includes a subset of the patches of said kernel version.
This is the part that bothers me the most. It seems like setting an "effective kernel version", when in fact it would be missing most of the patches from the corresponding real kernel, is actively misleading.
comment created time in 2 months
Pull request review commentdynup/kpatch
A shadow PID variable is allocated in `do_fork()`: it is associated with the current `struct task_struct *p` value, given a string lookup key of "newpid", sized accordingly, and allocated as per `GFP_KERNEL` flag rules. -`kpatch_shadow_alloc` returns a pointer to the shadow variable, so we can+`klp_shadow_get_or_alloc()` returns a pointer to the shadow variable, so we can
Ah, that makes sense now. I guess the correct fix would be to use klp_shadow_free_all() in a post-unload callback? If so it might be worth adding that to the real integration patches as well for proper test coverage.
comment created time in 2 months
pull request commentdynup/kpatch
create-diff-object: simplify mangled function correlation
This PR is now in shape for merging, once reviews are done.
comment created time in 2 months
push eventjpoimboe/kpatch
commit sha 935f1998752b050365993b05c7c44b64ee79c6c6
create-diff-object: simplify mangled function correlation The RHEL powerpc kernel is compiled with -O3, which triggers some "interesting" new optimizations. One of them, which seems to be relatively common, is the replacing of a function with two separate "constprop" functions. Previously we only ever saw a single constprop clone, so we just renamed the patched version of the function to match the original version. Now that we can have two such clones, that no longer makes sense. Instead of renaming functions, just improve the correlation logic such that they can be correlated despite having slightly different symbol names. The first clone in the original object is correlated with the first clone in the patched object; the second clone is correlated with the second clone; and so on. This assumes that the order of the symbols and sections doesn't change, which seems to be a reasonable assumption based on past experience with the compiler. Otherwise it will just unnecessarily mark the cloned constprop functions as changed, which is annoying but harmless, and noticeable by a human anyway. Fixes #935. Signed-off-by: Josh Poimboeuf <[email protected]>
push time in 2 months
push eventdynup/kpatch-unit-test-objs
commit sha 26b94a97bb093b8a236f243fc9f434f0053c6002
Add test for the powerpc "double constprop" issue This is a test for dynup/kpatch#935. The following patch was used with a RHEL7.8-based kernel: diff -Nupr src.orig/kernel/time/timekeeping.c src/kernel/time/timekeeping.c --- src.orig/kernel/time/timekeeping.c 2017-09-22 15:27:21.602055778 -0400 +++ src/kernel/time/timekeeping.c 2017-09-22 15:27:27.522080292 -0400 @@ -877,6 +877,9 @@ void do_gettimeofday(struct timeval *tv) { struct timespec64 now; + if (!tv) + return; + getnstimeofday64(&now); tv->tv_sec = now.tv_sec; tv->tv_usec = now.tv_nsec/1000; Signed-off-by: Josh Poimboeuf <[email protected]>
commit sha a5fd47f575552ef989b6b14de84460de5ce0b4ea
Merge pull request #18 from jpoimboe/double-constprop Add test for the powerpc "double constprop" issue
push time in 2 months
PR merged dynup/kpatch-unit-test-objs
This is a test for dynup/kpatch#935. The following patch was used with a RHEL7.8-based kernel:
diff -Nupr src.orig/kernel/time/timekeeping.c src/kernel/time/timekeeping.c --- src.orig/kernel/time/timekeeping.c 2017-09-22 15:27:21.602055778 -0400 +++ src/kernel/time/timekeeping.c 2017-09-22 15:27:27.522080292 -0400 @@ -877,6 +877,9 @@ void do_gettimeofday(struct timeval *tv) { struct timespec64 now;
- if (!tv)
-
return; - getnstimeofday64(&now); tv->tv_sec = now.tv_sec; tv->tv_usec = now.tv_nsec/1000;
Signed-off-by: Josh Poimboeuf [email protected]
pr closed time in 2 months
pull request commentdynup/kpatch
create-diff-object: simplify mangled function correlation
I think it is a normal submodule workflow. If we merge test-obj PR right now it won't affect the main repo since the submodule pointer will still use old commit-id, we can then add a commit updating the pointer to this PR so once it is merged we'll have both the test and accompanying changes. No races anywhere.
Right, of course.... Not sure how I managed to forget that. I'll go ahead and merge the test PR now.
comment created time in 2 months
pull request commentdynup/kpatch
create-diff-object: simplify mangled function correlation
I think it's a bit of a chicken-egg problem, but we can merge the test PR immediately before rebasing this commit with the updated test-objs pointer and then merging this PR.
comment created time in 2 months
push eventjpoimboe/kpatch
commit sha 3b832d382b5bdae2eb51073631861bf5cedae51a
create-diff-object: simplify mangled function correlation The RHEL powerpc kernel is compiled with -O3, which triggers some "interesting" new optimizations. One of them, which seems to be relatively common, is the replacing of a function with two separate "constprop" functions. Previously we only ever saw a single constprop clone, so we just renamed the patched version of the function to match the original version. Now that we can have two such clones, that no longer makes sense. Instead of renaming functions, just improve the correlation logic such that they can be correlated despite having slightly different symbol names. The first clone in the original object is correlated with the first clone in the patched object; the second clone is correlated with the second clone; and so on. This assumes that the order of the symbols and sections doesn't change, which seems to be a reasonable assumption based on past experience with the compiler. Otherwise it will just unnecessarily mark the cloned constprop functions as changed, which is annoying but harmless, and noticeable by a human anyway. Fixes #935. Signed-off-by: Josh Poimboeuf <[email protected]>
push time in 2 months
PR opened dynup/kpatch-unit-test-objs
This is a test for dynup/kpatch#935. The following patch was used with a RHEL7.8-based kernel:
diff -Nupr src.orig/kernel/time/timekeeping.c src/kernel/time/timekeeping.c --- src.orig/kernel/time/timekeeping.c 2017-09-22 15:27:21.602055778 -0400 +++ src/kernel/time/timekeeping.c 2017-09-22 15:27:27.522080292 -0400 @@ -877,6 +877,9 @@ void do_gettimeofday(struct timeval *tv) { struct timespec64 now;
- if (!tv)
-
return; - getnstimeofday64(&now); tv->tv_sec = now.tv_sec; tv->tv_usec = now.tv_nsec/1000;
Signed-off-by: Josh Poimboeuf [email protected]
pr created time in 2 months
create barnchjpoimboe/kpatch-unit-test-objs
created branch time in 2 months
pull request commentdynup/kpatch
create-diff-object: simplify mangled function correlation
I will add a powerpc unit test for this hopefully tomorrow.
comment created time in 2 months
PR opened dynup/kpatch
The RHEL powerpc kernel is compiled with -O3, which triggers some "interesting" new optimizations. One of them, which seems to be relatively common, is the replacing of a function with two separate "constprop" functions.
Previously we only ever saw a single constprop clone, so we just renamed the patched version of the function to match the original version. Now that we can have two such clones, that no longer makes sense.
Instead of renaming functions, just improve the correlation logic such that they can be correlated despite having slightly different symbol names. The first clone in the original object is correlated with the first clone in the patched object; the second clone is correlated with the second clone; and so on.
This assumes that the order of the symbols and sections doesn't change, which seems to be a reasonable assumption based on past experience with the compiler. Otherwise it will just unnecessarily mark the cloned constprop functions as changed, which is annoying but harmless, and noticeable by a human anyway.
Fixes #935.
Signed-off-by: Josh Poimboeuf [email protected]
pr created time in 2 months
Pull request review commentdynup/kpatch
structure can be used by patched code to handle both new (post-patch) and existing (pre-patch) instances. (This example is trimmed to highlight this use-case. Boilerplate code is also-required to allocate/free a shadow variable called "reqs_active_v2" whenever a-new `struct kioctx` is created/released. No values are ever assigned to the-shadow variable.)+required to allocate/free a shadow variable with enum ID SV_REQS_ACTIVE_V2
If it makes it more readable, why not go with the longer version? The extra characters are free. KLP_SV and KPS_ are cryptic, and ID_ doesn't make clear that it's a kpatch-specific id.
comment created time in 2 months
Pull request review commentdynup/kpatch
For example, a `pr_warn_once()` can be replaced with: pr_warn("..."); } ```++inline implies notrace+----------------------++The linux kernel defines its own version of "inline" in+include/linux/compiler_types.h which includes "notrace" as well:++```+#if !defined(CONFIG_OPTIMIZE_INLINING)+#define inline inline __attribute__((__always_inline__)) __gnu_inline \+ __inline_maybe_unused notrace+#else+#define inline inline __gnu_inline \+ __inline_maybe_unused notrace+#endif+```++With the implicit "notrace", use of "inline" in patch sources may lead+to kpatch-build errors like the following:++1. `__tcp_mtu_to_mss()` is marked as inline:++```+net/ipv4/tcp_output.c:++/* Calculate MSS not accounting any TCP options. */+static inline int __tcp_mtu_to_mss(struct sock *sk, int pmtu)+{+```++2. the compiler decides not to inline it and keeps it in its own+ function-section. Then kpatch-build notices that it doesn't have an+ fentry/mcount call:++```+% kpatch-build ...++tcp_output.o: function __tcp_mtu_to_mss has no fentry/mcount call, unable to patch+```++3. a peek at the generated code:++```+Disassembly of section .text.__tcp_mtu_to_mss:++0000000000000000 <__tcp_mtu_to_mss>:+ 0: 48 8b 87 60 05 00 00 mov 0x560(%rdi),%rax+ 7: 0f b7 50 30 movzwl 0x30(%rax),%edx+ b: 0f b7 40 32 movzwl 0x32(%rax),%eax+ f: 29 d6 sub %edx,%esi+ 11: 83 ee 14 sub $0x14,%esi+ ...+```++This could be a little confusing since one might have expected to see+changes to all of `__tcp_mtu_to_mss()` callers (ie, it was inlined as+requested). In this case, a simple workaround is to provide a new,+non-inlined copy of `__tcp_mtu_to_mss()` and then update all its callers+to use it.++Jump labels+-----------++When modifying a function that contains a jump label, kpatch-build may+return an error like: `ERROR: oom_kill.o: kpatch_regenerate_special_section: 2109: Found a jump label at out_of_memory()+0x10a, using key cpusets_enabled_key. Jump labels aren't currently supported. Use static_key_enabled() instead.`++This is due to a limitation in the kernel to process static key+livepatch relocations (resolved by late-module patching). Older+versions of kpatch-build may have reported successfully building +kpatch module, but issue+[#931](https://github.com/dynup/kpatch/issues/931) revealed potentially+dangerous behavior if the static key value had been modified from its+compiled default.++The current workaround is to remove the jump label by explictly checking+the static key:++```+/* unsupported */+if (static_key_true(&key1))++/* supported */+if (static_key_enabled(&key1))+```++Constant propagation symbol changes+-----------------------------------++GCC's constant propagation optimizations may result in kpatch-build+errors like: `ERROR: timekeeping.o: symbol changed sections: .text.timekeeping_update.constprop.9`++This is currently tracked as issue+[#935](https://github.com/dynup/kpatch/issues/935) "duplicate" mangled+fuctions. In that case, readelf revealed that kpatch-build wasn't+correleating constprop subfunctions created by the optimization:+```+# eu-readelf -s orig/kernel/time/timekeeping.o | grep timekeeping_update+ 137: 0000000000000000 552 FUNC LOCAL DEFAULT 48 timekeeping_update.constprop.9+ 138: 0000000000000000 568 FUNC LOCAL DEFAULT 50 timekeeping_update.constprop.8+# eu-readelf -s patched/kernel/time/timekeeping.o | grep timekeeping_update+ 137: 0000000000000000 552 FUNC LOCAL DEFAULT 48 timekeeping_update.constprop.10+ 138: 0000000000000000 568 FUNC LOCAL DEFAULT 50 timekeeping_update.constprop.9+```+The current workaround for this issue to add `__attribute__((noclone))`+to offending functions.++Sibling calls+-------------++If function A() calls function B() and they share a common function+signature, GCC may deem them "sibling calls" and apply a tail call
The signatures don't need to match because for sibling calls, A() restores the stack to its callee's state, and then sets up B()'s args appropriately before jumping to B().
comment created time in 2 months
Pull request review commentdynup/kpatch
A shadow PID variable is allocated in `do_fork()`: it is associated with the current `struct task_struct *p` value, given a string lookup key of "newpid", sized accordingly, and allocated as per `GFP_KERNEL` flag rules. -`kpatch_shadow_alloc` returns a pointer to the shadow variable, so we can+`klp_shadow_get_or_alloc()` returns a pointer to the shadow variable, so we can
How would klp_shadow_get_or_alloc() be more straightforward here? In do_fork() there shouldn't be an existing shadow struct for it, right?
comment created time in 2 months
Pull request review commentdynup/kpatch
test/integration: Rebase to RHEL 8.0
static void kpatch_bundle_symbols(struct kpatch_elf *kelf) } } +static void kpatch_add_child_symbol(struct symbol *parent, struct symbol *child)+{+ parent->nb_children++;+ parent->children = realloc(parent->children,+ sizeof(*parent->children) * parent->nb_children);+ child->parent = parent;+ parent->children[parent->nb_children - 1] = child;+}+ /* * During optimization gcc may move unlikely execution branches into *.cold- * subfunctions. kpatch_detect_child_functions detects such subfunctions and+ * subfunctions. Some functions can also be split into multiple *.part+ * functions.+ * kpatch_detect_child_functions detects such subfunctions and
Since we don't have a CI running these yet, I think I'd suggest doing the integration tests first, in one PR. That way the other fixes can refer to them.
comment created time in 2 months
Pull request review commentdynup/kpatch
test/integration: Rebase to RHEL 8.0
static void kpatch_bundle_symbols(struct kpatch_elf *kelf) } } +static void kpatch_add_child_symbol(struct symbol *parent, struct symbol *child)+{+ parent->nb_children++;+ parent->children = realloc(parent->children,+ sizeof(*parent->children) * parent->nb_children);+ child->parent = parent;+ parent->children[parent->nb_children - 1] = child;+}+ /* * During optimization gcc may move unlikely execution branches into *.cold- * subfunctions. kpatch_detect_child_functions detects such subfunctions and+ * subfunctions. Some functions can also be split into multiple *.part+ * functions.+ * kpatch_detect_child_functions detects such subfunctions and
Ah... I think I had a fundamental misunderstanding of this optimization. Looking at gcc/ipa-split.c in the GCC source confirms that. I had been thinking this was more like the constprop and isra optimizations.
So I take back my original comment! It's very similar to the .cold optimization and I think the parent/child relationship makes sense after all.
comment created time in 2 months
Pull request review commentdynup/kpatch
kmod: don't build module for kernels >=v5.2
# make rules KPATCH_BUILD ?= /lib/modules/$(shell uname -r)/build KERNELRELEASE := $(lastword $(subst /, , $(dir $(patsubst %/,%,$(KPATCH_BUILD)))))+VERCODE := $(shell awk '/LINUX_VERSION_CODE/{print $$NF}' $(KPATCH_BUILD)/include/generated/uapi/linux/version.h) THISDIR := $(abspath $(dir $(lastword $(MAKEFILE_LIST)))) ifeq ($(wildcard $(KPATCH_BUILD)),) $(error $(KPATCH_BUILD) doesn\'t exist. Try installing the kernel-devel-$(KERNELRELEASE) RPM or linux-headers-$(KERNELRELEASE) DEB.) endif +ifeq ($(shell if [ $(VERCODE) -lt 328192 ];then echo "y";fi),y) KPATCH_MAKE = $(MAKE) -C $(KPATCH_BUILD) M=$(THISDIR) kpatch.ko: core.c $(KPATCH_MAKE) kpatch.ko all: kpatch.ko+else+all:+$(info !!! Starting at v5.2, needed stacktrace routines are no longer available; not building kmod)
When running make from the top-level dir, I see this message twice because it does a clean first.
comment created time in 2 months
pull request commentdynup/kpatch
kmod: don't build module for kernels >=v5.2
* I wonder if it would be better to just remove the support module entirely? I would think the various kpatch-build kernel `CONFIG_` checks would indirectly enforce a minimum kernel version (and not worry about distro releases complicating the version code logic). It's code that we're bringing along, but not testing any longer... @jpoimboe thoughts?
I'd love to rip kpatch.ko out entirely, but I think it still has some users for older kernels, like @euspectre if I'm not mistaken.
comment created time in 2 months
Pull request review commentdynup/kpatch
A shadow PID variable is allocated in `do_fork()`: it is associated with the current `struct task_struct *p` value, given a string lookup key of "newpid", sized accordingly, and allocated as per `GFP_KERNEL` flag rules. -`kpatch_shadow_alloc` returns a pointer to the shadow variable, so we can+`klp_shadow_get_or_alloc()` returns a pointer to the shadow variable, so we can dereference and make assignments as usual. In this patch chunk, the shadow `newpid` is allocated then assigned to a rolling `ctr` counter value: ```+@@ -1797,6 +1798,13 @@ long do_fork(unsigned long clone_flags,+ if (!IS_ERR(p)) {+ struct completion vfork;+ struct pid *pid; + int *newpid; + static int ctr = 0; +-+ newpid = kpatch_shadow_alloc(p, "newpid", sizeof(*newpid),-+ GFP_KERNEL);++ newpid = klp_shadow_get_or_alloc(p, 0, sizeof(*newpid), GFP_KERNEL,
Maybe have #define KPATCH_SHADOW_NEWPID 0 somewhere (or enum) and use that instead? Perhaps along with a comment that the value needs to be globally unique.
comment created time in 2 months
Pull request review commentdynup/kpatch
the spinlock: return NULL; spin_lock_init(&sta->lock);-+ ps_lock = kpatch_shadow_alloc(sta, "ps_lock", sizeof(*ps_lock), gfp);++ ps_lock = klp_shadow_alloc(sta, PS_LOCK, sizeof(*ps_lock), gfp,
Similar comment here for PS_LOCK
comment created time in 2 months
Pull request review commentdynup/kpatch
structure can be used by patched code to handle both new (post-patch) and existing (pre-patch) instances. (This example is trimmed to highlight this use-case. Boilerplate code is also-required to allocate/free a shadow variable called "reqs_active_v2" whenever a-new `struct kioctx` is created/released. No values are ever assigned to the-shadow variable.)+required to allocate/free a shadow variable with enum ID SV_REQS_ACTIVE_V2
I had to do a double take at the SV_ prefix, maybe give it a KPATCH_SHADOW prefix instead? Also it might be clearer to define it somewhere in the code.
comment created time in 2 months
Pull request review commentdynup/kpatch
A shadow PID variable is allocated in `do_fork()`: it is associated with the current `struct task_struct *p` value, given a string lookup key of "newpid", sized accordingly, and allocated as per `GFP_KERNEL` flag rules. -`kpatch_shadow_alloc` returns a pointer to the shadow variable, so we can+`klp_shadow_get_or_alloc()` returns a pointer to the shadow variable, so we can dereference and make assignments as usual. In this patch chunk, the shadow `newpid` is allocated then assigned to a rolling `ctr` counter value: ```+@@ -1797,6 +1798,13 @@ long do_fork(unsigned long clone_flags,+ if (!IS_ERR(p)) {+ struct completion vfork;+ struct pid *pid; + int *newpid; + static int ctr = 0; +-+ newpid = kpatch_shadow_alloc(p, "newpid", sizeof(*newpid),-+ GFP_KERNEL);++ newpid = klp_shadow_get_or_alloc(p, 0, sizeof(*newpid), GFP_KERNEL,
Same question
comment created time in 2 months
Pull request review commentdynup/kpatch
A shadow PID variable is allocated in `do_fork()`: it is associated with the current `struct task_struct *p` value, given a string lookup key of "newpid", sized accordingly, and allocated as per `GFP_KERNEL` flag rules. -`kpatch_shadow_alloc` returns a pointer to the shadow variable, so we can+`klp_shadow_get_or_alloc()` returns a pointer to the shadow variable, so we can
Shouldn't this be klp_shadow_alloc()?
comment created time in 2 months
Pull request review commentdynup/kpatch
static void kpatch_post_unpatch_tcp_send_challenge_ack(patch_object *obj) +KPATCH_POST_UNPATCH_CALLBACK(kpatch_post_unpatch_tcp_send_challenge_ack); ``` -Don't forget to protect access to the data as needed. Please note that-spinlocks and mutexes / sleeping locks can't be used from stop_machine-context. Also note the pre-patch callback return code will be ignored by the-kernel's module notifier, so it does not affect the target module or livepatch-module status. This means:--* Pre-patch callbacks to loaded objects (vmlinux, loaded kernel modules) are- run from stop_machine(), so they may only inspect lock state (i.e.- spin_is_locked(), mutex_is_locked()) and optionally return -EBUSY to prevent- patching.--* Post-patch, pre-unpatch, and post-unpatch callbacks to loaded objects are- also run from stop_machine(), so the same locking context applies. No- return status is supported.--* Deferred pre-patch callbacks to newly loading objects do not run from- stop_machine(), so they may spin or schedule, i.e. spin_lock(),- mutex_lock()). Return status is ignored.--* Post-patch, pre-unpatch, and post-unpatch callbacks to unloading objects are- also *not* run from stop_machine(), so they may spin or sleep. No return- status is supported.--Unfortunately there is no simple, all-case-inclusive kpatch callback-implementation that handles data structures and mutual exclusion.--A few workarounds:--1. If a given lock/mutex is held and released by the same set of functions-(that is, functions that take a lock/mutex always release it before-returning), a trivial change to those functions can re-purpose kpatch's-activeness safety check to avoid patching when the lock/mutex may be held.-This assumes that all lock/mutex holders can be patched.+Don't forget to protect access to the data as needed. Spinlocks and mutexes /+sleeping locks **may be used** (this is a change of behavior from when kpatch+relied on the kpatch.ko support module and `stop_machine()` context.) -2. If it can be assured that all patch targets will be loaded before the-kpatch patch module, pre-patch callbacks may return -EBUSY if the lock/mutex-is held to block the patching.+Also note the pre-patch callback return code will be ignored by the kernel's+module notifier, so it does not affect the target module or livepatch module+status.
It will, however, prevent the patch from being enabled.
comment created time in 2 months
Pull request review commentdynup/kpatch
For example, a `pr_warn_once()` can be replaced with: pr_warn("..."); } ```++inline implies notrace+----------------------++The linux kernel defines its own version of "inline" in+include/linux/compiler_types.h which includes "notrace" as well:++```+#if !defined(CONFIG_OPTIMIZE_INLINING)+#define inline inline __attribute__((__always_inline__)) __gnu_inline \+ __inline_maybe_unused notrace+#else+#define inline inline __gnu_inline \+ __inline_maybe_unused notrace+#endif+```++With the implicit "notrace", use of "inline" in patch sources may lead+to kpatch-build errors like the following:++1. `__tcp_mtu_to_mss()` is marked as inline:++```+net/ipv4/tcp_output.c:++/* Calculate MSS not accounting any TCP options. */+static inline int __tcp_mtu_to_mss(struct sock *sk, int pmtu)+{+```++2. the compiler decides not to inline it and keeps it in its own+ function-section. Then kpatch-build notices that it doesn't have an+ fentry/mcount call:++```+% kpatch-build ...++tcp_output.o: function __tcp_mtu_to_mss has no fentry/mcount call, unable to patch+```++3. a peek at the generated code:++```+Disassembly of section .text.__tcp_mtu_to_mss:++0000000000000000 <__tcp_mtu_to_mss>:+ 0: 48 8b 87 60 05 00 00 mov 0x560(%rdi),%rax+ 7: 0f b7 50 30 movzwl 0x30(%rax),%edx+ b: 0f b7 40 32 movzwl 0x32(%rax),%eax+ f: 29 d6 sub %edx,%esi+ 11: 83 ee 14 sub $0x14,%esi+ ...+```++This could be a little confusing since one might have expected to see+changes to all of `__tcp_mtu_to_mss()` callers (ie, it was inlined as+requested). In this case, a simple workaround is to provide a new,+non-inlined copy of `__tcp_mtu_to_mss()` and then update all its callers+to use it.++Jump labels+-----------++When modifying a function that contains a jump label, kpatch-build may+return an error like: `ERROR: oom_kill.o: kpatch_regenerate_special_section: 2109: Found a jump label at out_of_memory()+0x10a, using key cpusets_enabled_key. Jump labels aren't currently supported. Use static_key_enabled() instead.`++This is due to a limitation in the kernel to process static key+livepatch relocations (resolved by late-module patching). Older+versions of kpatch-build may have reported successfully building +kpatch module, but issue+[#931](https://github.com/dynup/kpatch/issues/931) revealed potentially+dangerous behavior if the static key value had been modified from its+compiled default.++The current workaround is to remove the jump label by explictly checking+the static key:++```+/* unsupported */+if (static_key_true(&key1))++/* supported */+if (static_key_enabled(&key1))+```++Constant propagation symbol changes+-----------------------------------++GCC's constant propagation optimizations may result in kpatch-build+errors like: `ERROR: timekeeping.o: symbol changed sections: .text.timekeeping_update.constprop.9`++This is currently tracked as issue+[#935](https://github.com/dynup/kpatch/issues/935) "duplicate" mangled+fuctions. In that case, readelf revealed that kpatch-build wasn't+correleating constprop subfunctions created by the optimization:+```+# eu-readelf -s orig/kernel/time/timekeeping.o | grep timekeeping_update+ 137: 0000000000000000 552 FUNC LOCAL DEFAULT 48 timekeeping_update.constprop.9+ 138: 0000000000000000 568 FUNC LOCAL DEFAULT 50 timekeeping_update.constprop.8+# eu-readelf -s patched/kernel/time/timekeeping.o | grep timekeeping_update+ 137: 0000000000000000 552 FUNC LOCAL DEFAULT 48 timekeeping_update.constprop.10+ 138: 0000000000000000 568 FUNC LOCAL DEFAULT 50 timekeeping_update.constprop.9+```+The current workaround for this issue to add `__attribute__((noclone))`+to offending functions.++Sibling calls+-------------++If function A() calls function B() and they share a common function+signature, GCC may deem them "sibling calls" and apply a tail call+optimization in which the call to B() avoids the overhead of an ordinary+function call. This may be an issue for kpatches which only A() or B():
which only patch A() or B()?
comment created time in 2 months
Pull request review commentdynup/kpatch
For example, a `pr_warn_once()` can be replaced with: pr_warn("..."); } ```++inline implies notrace+----------------------++The linux kernel defines its own version of "inline" in+include/linux/compiler_types.h which includes "notrace" as well:++```+#if !defined(CONFIG_OPTIMIZE_INLINING)+#define inline inline __attribute__((__always_inline__)) __gnu_inline \+ __inline_maybe_unused notrace+#else+#define inline inline __gnu_inline \+ __inline_maybe_unused notrace+#endif+```++With the implicit "notrace", use of "inline" in patch sources may lead+to kpatch-build errors like the following:++1. `__tcp_mtu_to_mss()` is marked as inline:++```+net/ipv4/tcp_output.c:++/* Calculate MSS not accounting any TCP options. */+static inline int __tcp_mtu_to_mss(struct sock *sk, int pmtu)+{+```++2. the compiler decides not to inline it and keeps it in its own+ function-section. Then kpatch-build notices that it doesn't have an+ fentry/mcount call:++```+% kpatch-build ...++tcp_output.o: function __tcp_mtu_to_mss has no fentry/mcount call, unable to patch+```++3. a peek at the generated code:++```+Disassembly of section .text.__tcp_mtu_to_mss:++0000000000000000 <__tcp_mtu_to_mss>:+ 0: 48 8b 87 60 05 00 00 mov 0x560(%rdi),%rax+ 7: 0f b7 50 30 movzwl 0x30(%rax),%edx+ b: 0f b7 40 32 movzwl 0x32(%rax),%eax+ f: 29 d6 sub %edx,%esi+ 11: 83 ee 14 sub $0x14,%esi+ ...+```++This could be a little confusing since one might have expected to see+changes to all of `__tcp_mtu_to_mss()` callers (ie, it was inlined as+requested). In this case, a simple workaround is to provide a new,+non-inlined copy of `__tcp_mtu_to_mss()` and then update all its callers+to use it.++Jump labels+-----------++When modifying a function that contains a jump label, kpatch-build may+return an error like: `ERROR: oom_kill.o: kpatch_regenerate_special_section: 2109: Found a jump label at out_of_memory()+0x10a, using key cpusets_enabled_key. Jump labels aren't currently supported. Use static_key_enabled() instead.`++This is due to a limitation in the kernel to process static key+livepatch relocations (resolved by late-module patching). Older+versions of kpatch-build may have reported successfully building +kpatch module, but issue+[#931](https://github.com/dynup/kpatch/issues/931) revealed potentially+dangerous behavior if the static key value had been modified from its+compiled default.++The current workaround is to remove the jump label by explictly checking+the static key:++```+/* unsupported */+if (static_key_true(&key1))++/* supported */+if (static_key_enabled(&key1))+```++Constant propagation symbol changes+-----------------------------------++GCC's constant propagation optimizations may result in kpatch-build+errors like: `ERROR: timekeeping.o: symbol changed sections: .text.timekeeping_update.constprop.9`++This is currently tracked as issue+[#935](https://github.com/dynup/kpatch/issues/935) "duplicate" mangled+fuctions. In that case, readelf revealed that kpatch-build wasn't+correleating constprop subfunctions created by the optimization:+```+# eu-readelf -s orig/kernel/time/timekeeping.o | grep timekeeping_update+ 137: 0000000000000000 552 FUNC LOCAL DEFAULT 48 timekeeping_update.constprop.9+ 138: 0000000000000000 568 FUNC LOCAL DEFAULT 50 timekeeping_update.constprop.8+# eu-readelf -s patched/kernel/time/timekeeping.o | grep timekeeping_update+ 137: 0000000000000000 552 FUNC LOCAL DEFAULT 48 timekeeping_update.constprop.10+ 138: 0000000000000000 568 FUNC LOCAL DEFAULT 50 timekeeping_update.constprop.9+```+The current workaround for this issue to add `__attribute__((noclone))`+to offending functions.++Sibling calls+-------------++If function A() calls function B() and they share a common function+signature, GCC may deem them "sibling calls" and apply a tail call+optimization in which the call to B() avoids the overhead of an ordinary+function call. This may be an issue for kpatches which only A() or B():
It might also be worth mentioning somewhere that this is only an issue when the sibling call crosses a kernel module boundary, and only on powerpc.
comment created time in 2 months
Pull request review commentdynup/kpatch
For example, a `pr_warn_once()` can be replaced with: pr_warn("..."); } ```++inline implies notrace+----------------------++The linux kernel defines its own version of "inline" in+include/linux/compiler_types.h which includes "notrace" as well:++```+#if !defined(CONFIG_OPTIMIZE_INLINING)+#define inline inline __attribute__((__always_inline__)) __gnu_inline \+ __inline_maybe_unused notrace+#else+#define inline inline __gnu_inline \+ __inline_maybe_unused notrace+#endif+```++With the implicit "notrace", use of "inline" in patch sources may lead+to kpatch-build errors like the following:++1. `__tcp_mtu_to_mss()` is marked as inline:++```+net/ipv4/tcp_output.c:++/* Calculate MSS not accounting any TCP options. */+static inline int __tcp_mtu_to_mss(struct sock *sk, int pmtu)+{+```++2. the compiler decides not to inline it and keeps it in its own+ function-section. Then kpatch-build notices that it doesn't have an+ fentry/mcount call:++```+% kpatch-build ...++tcp_output.o: function __tcp_mtu_to_mss has no fentry/mcount call, unable to patch+```++3. a peek at the generated code:++```+Disassembly of section .text.__tcp_mtu_to_mss:++0000000000000000 <__tcp_mtu_to_mss>:+ 0: 48 8b 87 60 05 00 00 mov 0x560(%rdi),%rax+ 7: 0f b7 50 30 movzwl 0x30(%rax),%edx+ b: 0f b7 40 32 movzwl 0x32(%rax),%eax+ f: 29 d6 sub %edx,%esi+ 11: 83 ee 14 sub $0x14,%esi+ ...+```++This could be a little confusing since one might have expected to see+changes to all of `__tcp_mtu_to_mss()` callers (ie, it was inlined as+requested). In this case, a simple workaround is to provide a new,+non-inlined copy of `__tcp_mtu_to_mss()` and then update all its callers+to use it.++Jump labels+-----------++When modifying a function that contains a jump label, kpatch-build may+return an error like: `ERROR: oom_kill.o: kpatch_regenerate_special_section: 2109: Found a jump label at out_of_memory()+0x10a, using key cpusets_enabled_key. Jump labels aren't currently supported. Use static_key_enabled() instead.`++This is due to a limitation in the kernel to process static key+livepatch relocations (resolved by late-module patching). Older+versions of kpatch-build may have reported successfully building +kpatch module, but issue+[#931](https://github.com/dynup/kpatch/issues/931) revealed potentially+dangerous behavior if the static key value had been modified from its+compiled default.++The current workaround is to remove the jump label by explictly checking+the static key:++```+/* unsupported */+if (static_key_true(&key1))++/* supported */+if (static_key_enabled(&key1))+```++Constant propagation symbol changes+-----------------------------------++GCC's constant propagation optimizations may result in kpatch-build+errors like: `ERROR: timekeeping.o: symbol changed sections: .text.timekeeping_update.constprop.9`++This is currently tracked as issue+[#935](https://github.com/dynup/kpatch/issues/935) "duplicate" mangled+fuctions. In that case, readelf revealed that kpatch-build wasn't+correleating constprop subfunctions created by the optimization:+```+# eu-readelf -s orig/kernel/time/timekeeping.o | grep timekeeping_update+ 137: 0000000000000000 552 FUNC LOCAL DEFAULT 48 timekeeping_update.constprop.9+ 138: 0000000000000000 568 FUNC LOCAL DEFAULT 50 timekeeping_update.constprop.8+# eu-readelf -s patched/kernel/time/timekeeping.o | grep timekeeping_update+ 137: 0000000000000000 552 FUNC LOCAL DEFAULT 48 timekeeping_update.constprop.10+ 138: 0000000000000000 568 FUNC LOCAL DEFAULT 50 timekeeping_update.constprop.9+```+The current workaround for this issue to add `__attribute__((noclone))`+to offending functions.++Sibling calls+-------------++If function A() calls function B() and they share a common function+signature, GCC may deem them "sibling calls" and apply a tail call
A shared function signature isn't necessarily required. The return values need to be compatible, and the call to B() is usually done at the end of A(). But it's complicated... might be easiest to just not describe the preconditions in the first place :-)
comment created time in 2 months
Pull request review commentdynup/kpatch
For example, a `pr_warn_once()` can be replaced with: pr_warn("..."); } ```++inline implies notrace+----------------------++The linux kernel defines its own version of "inline" in+include/linux/compiler_types.h which includes "notrace" as well:++```+#if !defined(CONFIG_OPTIMIZE_INLINING)+#define inline inline __attribute__((__always_inline__)) __gnu_inline \+ __inline_maybe_unused notrace+#else+#define inline inline __gnu_inline \+ __inline_maybe_unused notrace+#endif+```++With the implicit "notrace", use of "inline" in patch sources may lead+to kpatch-build errors like the following:++1. `__tcp_mtu_to_mss()` is marked as inline:++```+net/ipv4/tcp_output.c:++/* Calculate MSS not accounting any TCP options. */+static inline int __tcp_mtu_to_mss(struct sock *sk, int pmtu)+{+```++2. the compiler decides not to inline it and keeps it in its own+ function-section. Then kpatch-build notices that it doesn't have an+ fentry/mcount call:++```+% kpatch-build ...++tcp_output.o: function __tcp_mtu_to_mss has no fentry/mcount call, unable to patch+```++3. a peek at the generated code:++```+Disassembly of section .text.__tcp_mtu_to_mss:++0000000000000000 <__tcp_mtu_to_mss>:+ 0: 48 8b 87 60 05 00 00 mov 0x560(%rdi),%rax+ 7: 0f b7 50 30 movzwl 0x30(%rax),%edx+ b: 0f b7 40 32 movzwl 0x32(%rax),%eax+ f: 29 d6 sub %edx,%esi+ 11: 83 ee 14 sub $0x14,%esi+ ...+```++This could be a little confusing since one might have expected to see+changes to all of `__tcp_mtu_to_mss()` callers (ie, it was inlined as+requested). In this case, a simple workaround is to provide a new,+non-inlined copy of `__tcp_mtu_to_mss()` and then update all its callers+to use it.
Alternatively you could change it to __always_inline.
comment created time in 2 months
Pull request review commentdynup/kpatch
test/integration: Rebase to RHEL 8.0
static void kpatch_bundle_symbols(struct kpatch_elf *kelf) } } +static void kpatch_add_child_symbol(struct symbol *parent, struct symbol *child)+{+ parent->nb_children++;+ parent->children = realloc(parent->children,+ sizeof(*parent->children) * parent->nb_children);+ child->parent = parent;+ parent->children[parent->nb_children - 1] = child;+}+ /* * During optimization gcc may move unlikely execution branches into *.cold- * subfunctions. kpatch_detect_child_functions detects such subfunctions and+ * subfunctions. Some functions can also be split into multiple *.part+ * functions.+ * kpatch_detect_child_functions detects such subfunctions and
Hm. Does the patched audit_log_end() also reference the "lock" static local variable? IIRC, "part" functions are clones of the originals. So it seems like audit_log_end() should also reference the static local, unless I'm missing something.
comment created time in 2 months
Pull request review commentdynup/kpatch
test/integration: Rebase to RHEL 8.0
static void kpatch_bundle_symbols(struct kpatch_elf *kelf) } } +static void kpatch_add_child_symbol(struct symbol *parent, struct symbol *child)+{+ parent->nb_children++;+ parent->children = realloc(parent->children,+ sizeof(*parent->children) * parent->nb_children);+ child->parent = parent;+ parent->children[parent->nb_children - 1] = child;+}+ /* * During optimization gcc may move unlikely execution branches into *.cold- * subfunctions. kpatch_detect_child_functions detects such subfunctions and+ * subfunctions. Some functions can also be split into multiple *.part+ * functions.+ * kpatch_detect_child_functions detects such subfunctions and
I'm not sure a ".part" function can be considered a "child". In the context of this code, a child (or subfunction) means that it's a ".cold" extension of the parent function, where the parent function can branch to the child subfunction.
But in the case of ".part", I believe it's an optimized clone of the original function. But otherwise the functions have no relation -- i.e. they are independent and the parent doesn't branch to the clone.
Or maybe I'm misunderstanding. Was there a patch which showed this behavior?
comment created time in 2 months
push eventdynup/kpatch
commit sha e9755413ed58c8d40b615552e84ff9c5e80acc57
kpatch-build: use whole word filename matching in find_parent_obj() Building a kpatch for a module with this Makefile: The Makefile is as follow: obj-m += m_hello.o m_hello-y = hello.o default: $(MAKE) -C /lib/modules/4.4.21-69-default/build M=$(shell pwd) modules clean: $(MAKE) -C /lib/modules/4.4.21-69-default/build M=$(shell pwd) clean results in kpatch-build "ERROR: two parent matches for hello.o". The problem is that find_parent_obj() looks for filenames like so: % grep -l hello.o ./.*.cmd | grep -Fv hello.o .m_hello.ko.cmd .m_hello.o.cmd where .m_hello.ko.cmd is the parant for m_hello.o, and .m_hello.o.cmd is the parant for hello.o, but because the "hello.o" is a substring of "m_hello.o", it will cause "m_hello.o" to be matched for the "hello.o" as well. Fix this by using grep's -w|--word-regexp option to force it to match whole words instead of substrings. Signed-off-by: chenzefeng <[email protected]>
commit sha 683289206bed3ee9296406da4ec58b881c408507
Merge pull request #1038 from wwheart/master kpatch-build: fix two parent matches error
push time in 2 months
PR merged dynup/kpatch
when I make a patch for a module, cause the error as follow: ERROR: two parent matches for hello.o. Check /tmp/kpatch-build.log for more details.
The Makefile is as follow: obj-m += m_hello.o m_hello-y = hello.o default: $(MAKE) -C /lib/modules/4.4.21-69-default/build M=$(shell pwd) modules clean: $(MAKE) -C /lib/modules/4.4.21-69-default/build M=$(shell pwd) clean
and than cmd "grep -l hello.o ./.*.cmd | grep -Fv hello.o" would get two parant .m_hello.ko.cmd .m_hello.o.cmd but the ".m_hello.ko.cmd" is the parant for "m_hello.o", and ".m_hello.o.cmd" is the parant for "hello.o".
because the "hello.o" is a substring of "m_hello.o", which will cause the "m_hello.o" matched for the "hello.o".
Signed-off-by: chenzefeng [email protected]
pr closed time in 2 months
push eventdynup/kpatch
commit sha 50476c94cc9549ea9b421b3e2a5638ffe1a2e5a9
create-diff-object: Check ELF headers earlier There is no point inspecting through the symbols of the ELF files (original and patched) when the ELF headers do not meet requirements. Check ELF headers as soon as the files are mapped. Signed-off-by: Julien Thierry <[email protected]>
commit sha bd4fae25f90659bf39bab2e7614f4fd3015af9ff
create-diff-object: Add const to unmodified rela_insn arguments rela_insn() only retrieves information about an instruction and does not modify sections or relocations. Add const to make this explicit. Signed-off-by: Julien Thierry <[email protected]>
commit sha 878bac379f2a1393446e8e01bebc0952620c16aa
create-diff-object: Simplify relocation processing If the symbol associated with a relocation does not have a section set, nothing is done for that relocation. Skip iterating through all the symbols of the ELF file in such a case. Signed-off-by: Julien Thierry <[email protected]>
commit sha c175d8697c7aa8e155a86c3cd917da6b1a912427
Merge pull request #1039 from julien-thierry/misc-cleanups Misc cleanups
push time in 2 months
PR merged dynup/kpatch
Some suggestion of cleanups I stumbled upon while trying to understand the code.
pr closed time in 2 months
push eventdynup/kpatch
commit sha 52d4936e728629ebb725de37574cbeed231dbcd5
integration/rhel-*: fix multiple.test When these from internal depths of Red Hat upstream paths changed and now we are one level deeper in directory tree. The issue probably also exist in rhel8.0 rebase pr #993. Signed-off-by: Artem Savkov <[email protected]>
commit sha d131d43656b191d6b47772591c306dc9a4c68852
Merge pull request #1040 from sm00th/multiple_test integration/rhel-*: fix multiple.test
push time in 2 months
PR merged dynup/kpatch
When these from internal depths of Red Hat upstream paths changed and now we are one level deeper in directory tree.
The issue probably also exist in rhel8.0 rebase pr #993.
pr closed time in 2 months
issue commentClangBuiltLinux/linux
missing symbol for section .text, .init.text, .ref.text
@nickdesaulniers I think it just means that the section symbols associated with those sections are missing. It's not necessarily a bug, I'd need to see the .o file to know more.
comment created time in 2 months
push eventdynup/kpatch
commit sha 2499eb2bdcd0652c5138effecf2bed3aac90a3d7
Revert "create-diff-object: Check for *_fixup sections changes" We are seeing the following error on a real world patch: unsupported reference to special section __barrier_nospec_fixup The kpatch commit bb444c2168d1 ("create-diff-object: Check for *_fixup sections changes") created this error because we were trying to be future proof. However, that may have been overly paranoid, as it doesn't seem likely that those fixup sections will need relocations anytime soon, because the replacement instructions are manually generated in code. And anyway that "future proof" commit breaks the present. Also we decided at LPC that we are going to remove .klp.arch sections anyway, so once that happens we will be fully future-proof anyway. This reverts commit bb444c2168d17ba7a67a2329ea7ed6f9b37b45cc. Fixes #974. Signed-off-by: Josh Poimboeuf <[email protected]>
commit sha 0b000cb87d88ea9dd5983ea3effb7b7e5326abc1
Merge pull request #1037 from jpoimboe/ppc64le-remove-unsupported-check Revert "create-diff-object: Check for *_fixup sections changes"
push time in 2 months
PR merged dynup/kpatch
We are seeing the following error on a real world patch:
unsupported reference to special section __barrier_nospec_fixup
The kpatch commit bb444c2168d1 ("create-diff-object: Check for *_fixup sections changes") created this error because we were trying to be future proof. However, that may have been overly paranoid, as it doesn't seem likely that those fixup sections will need relocations anytime soon, because the replacement instructions are manually generated in code. And anyway that "future proof" commit breaks the present.
Also we decided at LPC that we are going to remove .klp.arch sections anyway, so once that happens we will be fully future-proof anyway.
This reverts commit bb444c2168d17ba7a67a2329ea7ed6f9b37b45cc.
Fixes #974.
Signed-off-by: Josh Poimboeuf [email protected]
pr closed time in 2 months
issue closeddynup/kpatch
powerpc: support alternatives (aka feature fixups)
As mentioned in #963, I think we have two gaps in powerpc support related to alternatives ("feature fixups"):
- kpatch-build doesn't create .klp.arch sections
- the kernel powerpc arch livepatch code doesn't read .klp.arch sections
At least in theory this means that if any of the feature fixup sections refers to a patched function, and the alternative original code has klp relas associated with it, code corruption may occur when the klp relas clobber the copied alternative replacement code, thinking that it's the alternative original code.
Phase 1 fix:
- For kernel versions which don't have livepatch-specific powerpc code (currently all kernel versions), kpatch-build needs to assert an error if it detects that one of the following sections refers to a patched function: __ftr_fixup, __mmu_ftr_fixup, __fw_ftr_fixup.
Phase 2 fix:
- The upstream kernel needs a powerpc implementation of arch_klp_init_object_loaded().
- kpatch-build needs to create klp.arch sections for powerpc for those kernel versions, instead of the phase 1 error
Phase 3 fix:
- Convince upstream that loading patches for modules which haven't been loaded yet is still a bad idea. The easiest solution is just to modprobe all target modules before loading the patch.
- Remove all these .klp section hacks
closed time in 2 months
jpoimboepush eventdynup/kpatch
commit sha aabdf9c9c929dbaf43705a1211941f687297b3cf
Fix parent matches for kernels newer than 5.3 Somewhere starting with 5.3 (probably with 9f69a496f100 "kbuild: split out *.mod out of {single,multi}-used-m rules", but that is not confirmed) .mod and correcponding .mod.cmd files started showing up during module builds throwing off kpatch-build's find_parent_obj() func. Filter out any files ending with .mod.cmd as they are definitely not the parent. Signed-off-by: Artem Savkov <[email protected]>
commit sha 7a9fc1fbc8e912a697a619581d320cb09c91b774
Merge pull request #1036 from sm00th/mod_cmd Fix parent matches for kernels newer than 5.3
push time in 2 months
PR merged dynup/kpatch
Somewhere starting with 5.3 (probably with 9f69a496f100 "kbuild: split out *.mod out of {single,multi}-used-m rules", but that is not confirmed) .mod and correcponding .mod.cmd files started showing up during module builds throwing off kpatch-build's find_parent_obj() func.
Filter out any files ending with .mod.cmd as they are definitely not the parent.
pr closed time in 2 months
PR opened dynup/kpatch
We are seeing the following error on a real world patch:
unsupported reference to special section __barrier_nospec_fixup
The kpatch commit bb444c2168d1 ("create-diff-object: Check for *_fixup sections changes") created this error because we were trying to be future proof. However, that may have been overly paranoid, as it doesn't seem likely that those fixup sections will need relocations anytime soon, because the replacement instructions are manually generated in code. And anyway that "future proof" commit breaks the present.
Also we decided at LPC that we are going to remove .klp.arch sections anyway, so once that happens we will be fully future-proof anyway.
This reverts commit bb444c2168d17ba7a67a2329ea7ed6f9b37b45cc.
Fixes #974.
Signed-off-by: Josh Poimboeuf [email protected]
pr created time in 2 months
push eventjpoimboe/kpatch
commit sha 2499eb2bdcd0652c5138effecf2bed3aac90a3d7
Revert "create-diff-object: Check for *_fixup sections changes" We are seeing the following error on a real world patch: unsupported reference to special section __barrier_nospec_fixup The kpatch commit bb444c2168d1 ("create-diff-object: Check for *_fixup sections changes") created this error because we were trying to be future proof. However, that may have been overly paranoid, as it doesn't seem likely that those fixup sections will need relocations anytime soon, because the replacement instructions are manually generated in code. And anyway that "future proof" commit breaks the present. Also we decided at LPC that we are going to remove .klp.arch sections anyway, so once that happens we will be fully future-proof anyway. This reverts commit bb444c2168d17ba7a67a2329ea7ed6f9b37b45cc. Fixes #974. Signed-off-by: Josh Poimboeuf <[email protected]>
push time in 2 months
create barnchjpoimboe/kpatch
branch : ppc64le-remove-unsupported-check
created branch time in 2 months
issue commentdynup/kpatch
powerpc: support alternatives (aka feature fixups)
And going through them manually, none of them appear to rely on relocations.
So this appears to be a false alarm. I think we are safe. And we can probably get by without .klp.arch sections on powerpc. (@kamalesh-babulal I can't remember if we talked about this previously)
But to be future-proof we should at least detect the usage of those sections in a patched function and error out in kpatch-build.
I now disagree with my past self here. We have a recent patch which shows:
unsupported reference to special section __barrier_nospec_fixup
There's no real reason to enforce this, since as I said above, "we are safe". And also we will eventually be getting rid of .klp.arch sections anyway, as discussed at LPC. I will post a patch to remove 'unsupported' for these sections.
comment created time in 2 months
startedSUSE/klp-ccp
started time in 3 months
Pull request review commentdynup/kpatch
kpatch-build: Check if /etc/os-release exists
fi [[ -z "$TARGETS" ]] && TARGETS="vmlinux modules" # Don't check external file.-# shellcheck disable=SC1091-source /etc/os-release+# shellcheck disable=SC1090+[ -f "$RELEASE_FILE" ] && source "$RELEASE_FILE"
style nit: we use double brackets everywhere
comment created time in 3 months
pull request commentdynup/kpatch
kpatch-build: sanity check patched filenames
As far as removing the checks in kpatch-gcc, I don't think we can do that as this commit only checks direct changes to those source files. A header file change could slip through and still modify an end object file, so I think kpatch-gcc needs to keep its checks intact.
Agreed
comment created time in 3 months
pull request commentdynup/kpatch
kpatch-build: sanity check patched filenames
Not that I can think of, but you might want to look at all the files that are ignored by kpatch-gcc. For example, it ignores lib/ files. That check can probably be removed now? There might be others as well.
comment created time in 3 months
Pull request review commentdynup/kpatch
test/integration: add an ability to check specific repo/commit
#!/bin/bash KPATCH_SLOW=0+KPATCH_GIT=${KPATCH_GIT:-https://github.com/dynup/kpatch.git}+KPATCH_REV=${KPATCH_REV:-HEAD} LOGDIR="/vagrant/logs" usage() { echo "usage: $(basename "${0}") [options]" >&2- echo "-h, --help This message" >&2- echo "-s, --slow Run all of the tests" >&2+ echo "-h, --help This message" >&2+ echo "-s, --slow Run all of the tests" >&2+ echo "-g, --git Git url to clone from" >&2+ echo "-r, --revision Revision to use (HEAD by default)" >&2 } -options="$(getopt -o s -l "slow" -- "$@")" || "getopt failed"+options="$(getopt -o "shg:r:" -l "slow,help,git:,revision:" -- "$@")" || "getopt failed" eval set -- "${options}" while [[ $# -gt 0 ]]; do case "$1" in -s|--slow) KPATCH_SLOW=1+ shift+ ;;+ -g|--git)+ KPATCH_GIT="${2}"+ shift 2+ ;;+ -r|--revision)+ KPATCH_REV="${2}"+ shift 2 ;; -h|--help) usage exit 0 ;;+ --)+ shift+ break+ ;; esac- shift done -git clone https://github.com/dynup/kpatch.git || exit 1+git clone "${KPATCH_GIT}" || exit 1 cd kpatch || exit 1 +git reset --hard "${KPATCH_REV}" || exit 1
Ah, right. Though since it's run in a VM and it's a fresh clone I guess there shouldn't be any local changes anyway? I guess either way works.
comment created time in 3 months