This release has many fixes and improvements since 0.3.4. The '0.3' was
bumped to '0.4' because of commit 0bb5c106ef ("kmod: restructure
kpatch sysfs tree"), which broke the ABI between the kpatch core module
and the kpatch script, as it changed the sysfs layout.
Other notable changes since 0.3.4:
- The tools underlying kpatch-build have been made more modular, in
preparation for making create-diff-object more generally useful to
other use cases (kernel livepatch, Xen live patching, user space
patching).
- Support for all new upstream kernels up to 4.10.
- KASLR support.
- Many other bug fixes and improvements.
* remove the Fedora release number
* add part of the $(uname -r) to kernel package specifications
* add patchutils as an optional package to satisfy kpatch-test
* update to the latest ccache rpm URL @ dl.fedoraproject.org
Upstream kernel commit 7f2084fa55e6 ("[kbuild] handle exports in lib-y
objects reliably") (v4.9+) added temporary dummy .lib_exports.o objects
to the kernel build. As these ephemeral files don't contain any code,
update the kpatch-gcc glob pattern to ignore them.
(glob pattern suggested by flaming-toast)
Fixes#686.
Strip kpatch_ignore_func_* and __UNIQUE_ID_kpatch_ignore_section_*
symbols to prevent the inclusion of .kpatch.ignore.functions and
.kpatch.ignore.sections. Mark the symbols as SAME, otherwise they are
considered NEW and are recursively included. This includes the
corresponding ignore sections and rela sections and may also create new,
unnecessary dynrelas.
Signed-off-by: Ross Lagerwall <ross.lagerwall@citrix.com>
A couple of minor cleanups:
- move the `if (locals)` check to find_local_syms()
- remove the explicit initialization of `local_syms`, the entire struct
was already previously cleared to zero.
When the core module loops through an object's list of dynrelas, it
determines whether or not the target location of the dynrela is in a
read-only region of the patch module. If it is, the readonly flag is set to
1 and it calls set_memory_{rw,ro} before and after the probe_kernel_write()
operation. This flag gets set once, and never gets reset for subsequent
iterations. Therefore, if a target happens to be in a RW section of the
patch module, and readonly = 1 had been set before, we may unintentionally
set a normally RW page to RO. Fix this by setting the readonly flag with
each iteration of the loop.
Fixes#681.
When wiping out the ~/.kpatch cache before replacing it with a new
kernel source, there's no need to keep anything around. Just wipe it
all out and start over.
Also, when building with the -s option, it doesn't need to touch
~/.kpatch/version or ~/.kpatch/src, so it can just skip the cleaning.
That keeps the previous cache around for the next incantation of
kpatch-build without '-s'.
Once upon a time, kpatch-build did the kernel build in three passes.
The extra pass was done without '-ffunction-sections -fdata-sections',
so it could produce the original vmlinux file.
At that time, there was no ~/.kpatch/obj directory. The kernel was
built directly in ~/.kpatch/src. Because the same directory was used
for both the original kernel build and the '-ffunction-sections
-fdata-sections' build, the entire tree had to be rebuilt twice for
every kpatch-build incantation, making it very slow.
That situation was improved with the following commit:
5352d8b01a ("build objects in separate directory to fix caching")
That built the regular and special binaries in ~/.kpatch/obj and
~/.kpatch/obj2, respectively.
Since then we've simplified things so that it only does two build
passes: original and patched, both with '-ffunction-sections
-fdata-sections', and ~/.kpatch/obj2 was removed. However,
~/.kpatch/obj still remained. That's because we never had a reason to
change it, until now.
Recent commit aa2907df29 ("support dup file+symbol")
triggers a new warning:
create-diff-object: ERROR: dynamic_debug.o: find_local_syms: 124: find_local_syms for dynamic_debug.c: found_none
This was actually a preexisting issue which that commit helped uncover.
The root issue is that dynamic_debug.c has some creative uses of the
`__FILE__` macro. When building the kernel objects outside the source
tree, the macro results in a absolute path like:
/home/jpoimboe/.kpatch/src/lib/dynamic_debug.c
But when building inside the source tree it's a relative path:
lib/dynamic_debug.c
The Fedora kernel is built in-tree, and I would imagine most other
distros are also built that way. So the way kpatch builds can result in
a slightly different 'original' object than the distro version, thanks
to the __FILE__ macro.
In this case, the order of the symbol table changed slightly between
vmlinux and the 'orig' object. Presumably, the difference in string
lengths was enough to convince the compiler to shuffle things around a
bit.
So considering that bug, and the possibility of other mismatches, go
back to building the kernel in the source tree.
For some reason, the backticks on this line confuse my editor's syntax
highlighter! Make vim happy by using the other form of command
substition.
Also convert the function definition syntax to comply with the
kpatch-build coding guidelines ;-)
A few symbols are discarded in the kernel linking phase, which means
they won't be in the lookup table. Skip their comparison.
This fixes a bunch of warnings seen when building a patch which triggers
a tree-wide rebuild:
create-diff-object: ERROR: aes_glue.o: find_local_syms: 112: find_local_syms for aes_glue.c: found_none
create-diff-object: ERROR: aesni-intel_glue.o: find_local_syms: 112: find_local_syms for aesni-intel_glue.c: found_none
create-diff-object: ERROR: init.o: find_local_syms: 112: find_local_syms for init.c: found_none
create-diff-object: ERROR: iosf_mbi.o: find_local_syms: 112: find_local_syms for iosf_mbi.c: found_none
create-diff-object: ERROR: setup.o: find_local_syms: 112: find_local_syms for setup.c: found_none
...
After this patch, there's still one warning remaining:
create-diff-object: ERROR: dynamic_debug.o: find_local_syms: 133: find_local_syms for dynamic_debug.c: found_none
That one has a completely different cause, which I'll fix in another
pull request (coming soon).
Fixes: #676
Normal correlated symbols are marked the SAME initially but static local
variables are correlated in a separate function. Also mark these the
SAME.
This fixes an issue where patching a function which called printk_once
(which uses a static local variable) would fail to build because the
static local variable was considered new and thus introduced a new data
member into .data..read_mostly which is not allowed to change.
Signed-off-by: Ross Lagerwall <ross.lagerwall@citrix.com>
Restructure kpatch's sysfs interface and mirror the sysfs tree after
livepatch's sysfs layout. With the current sysfs layout, we cannot
distinguish which object a function belongs to, and we cannot tell which
modules/objects are patched. Therefore, restructure the kpatch sysfs tree
such that module/object information is available. With the new layout, each
patched object has its own directory, with each function being a
subdirectory of its object.
Implement this by embedding a kobject struct within the kpatch_module,
kpatch_func, and kpatch_object structs and supplying their ktypes and
kobject release methods.
Before:
/sys/kernel/kpatch
└── patches
└── <patch_module>
├── checksum
├── enabled
└── functions
├── <function> # from <object1>
│ ├── new_addr
│ └── old_addr
├── <function> # from <object2>
│ ├── new_addr
│ └── old_addr
└─── <function> # from <object3>
├── new_addr
└── old_addr
After:
/sys/kernel/kpatch
└── <patch_module>
├── <object1>
│ └── <function,sympos>
│ ├── new_addr
│ └── old_addr
├── <object2>
│ └── <function,sympos>
│ ├── new_addr
│ └── old_addr
├── checksum
├── enabled
└── <object3>
└── <function,sympos>
├── new_addr
└── old_addr
Rename a couple of the variables in find_local_syms() to better reflect
their purpose. The passed in 'locals' are from the childobj (e.g.
foo.o) rather than the parent (e.g. vmlinux).
When CONFIG_DEBUG_ATOMIC_SLEEP is enabled, might_sleep calls will add
the line number to the instruction stream. Detect and ignore any such
changes.
Fixes: #657.
CONFIG_PARAVIRT is not required for building kpatch patch modules. The
sizeof paravirt_patch_site struct was only needed to create
.parainstructions sections as part of create-diff-object. As long as
the original objects were built without such sections then
this kernel option (and struct handling) can be considered optional.
The CONFIG_DEBUG_INFO_SPLIT kernel .config option places debug
information into separate .dwo files. As no known distribution is
currently shipping .dwo in their debuginfo packages, leave it as
unsupported for now.
When building a kernel with CONFIG_DEBUG_INFO_REDUCED, it was observed
that subsequent readelf -wi output may not always display structure size
information first. The affects the kpatch-build awk script that needs
to consider readelf output like the following:
<1><26393>: Abbrev Number: 12 (DW_TAG_structure_type)
<26394> DW_AT_name : (indirect string, offset: 0x914f): alt_instr
<26398> DW_AT_declaration : 12
...
<1><169d1b>: Abbrev Number: 13 (DW_TAG_structure_type)
<169d1c> DW_AT_name : (indirect string, offset: 0x914f): alt_instr
<169d20> DW_AT_byte_size : 13
Therefore the awk state machine should reset if it doesn't encounter
"DW_AT_byte_size" after given structure name match.
Fixes: #668.
Support for gawk '\s' (whitespace) GNU Regexp Operator was added
somewhere between gawk 3 and 4 (RHEL6 and RHEL7). Use the [[:space:]]
bracket expression to support older releases of gawk.
We use kelf_base->symbols to find a unique matching FILE+locals combination
when we call lookup_open(). If we can't find one matching or we find more
than one matching, we error out.
If we find a unique one, we setup table->local_syms in lookup_open(),
so later lookup_local_symbol() could do its lookup based on table->local_syms.
Fixes#604.
Suggested-by: Josh Poimboeuf <jpoimboe@redhat.com>
Signed-off-by: Zhou Chengming <zhouchengming1@huawei.com>
Upstream 2992ef29ae01 "livepatch/module: make TAINT_LIVEPATCH module-specific"
added a TAINT_LIVEPATCH flag to the module-specific taint flags. This
commit is v4.9+ and the modules taint field is an unsigned int.
Upstream 7fd8329ba502 "taint/module: Clean up global and module taint
flags handling" modified the modules taint field to be an unsigned long.
This commit is v4.10+.
Adjust the module tainting code in kpatch_register() to consider v4.9
kernels as well as v4.10 (and any distro-specific behavior).
Fixes: #666.