Home Home > GIT Browse
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicolai Stange <nstange@suse.de>2017-10-31 10:34:52 +0100
committerMiroslav Benes <mbenes@suse.cz>2017-12-08 13:03:35 +0100
commit0fe721be0894cac6d25b13ef0f575a554345e321 (patch)
tree7ef444830c5fd6b35ceb2158789738bb59bf8cda
parentff32fc92b1250549d9e732984a9fd9af59dce57a (diff)
scripts/register_patches.sh: generate klp_object array
The KLP API doesn't take a flat list of to be patched functions like KGraft did, but introduces an intermediate layer: struct klp_object. Each klp_patch instance is supposed to reference an array of klp_object's which in turn provide an array of klp_func's each. To facilitate merging, we want to generate this list of klp_object's automatically, exactly like we did for the flat function list with KGraft. For each klp_patch instance, there must be at most one klp_object entry referring to the same object. Hence care must be taken not to add an entry for the same object twice in case two different (sub-)patches both patch some functions therein. Require from each (sub-)patch to provide the list of to be patched symbols in a file named SUBPATCH/patched_funcs.csv with each line conforming to the obj old_func(,sympos) new_func pattern. Make scripts/register.sh generate an klp_object array initializer based on this and let it expand the @@KLP_PATCHES_OBJS@@ tag within livepatch_main.c accordingly. Do not replace the now obsolete @@KLP_PATCHES_FUNCS@@ anymore. Add and remove the @@KLP_PATCHES_OBJS@@ and @@KLP_PATCHES_FUNCS@@ markers to and from livepatch_main.c respectively. Signed-off-by: Nicolai Stange <nstange@suse.de> [ mb: amend copy&paste error ($newfun at the end of uname klp_func[]) ] Signed-off-by: Miroslav Benes <mbenes@suse.cz>
-rw-r--r--livepatch_main.c16
-rwxr-xr-xscripts/register-patches.sh76
2 files changed, 66 insertions, 26 deletions
diff --git a/livepatch_main.c b/livepatch_main.c
index 4a4e7be..c002ac5 100644
--- a/livepatch_main.c
+++ b/livepatch_main.c
@@ -26,22 +26,8 @@
@@KLP_PATCHES_INCLUDES@@
-static struct klp_func vmlinux_funcs[] = {
- {
- .old_name = "SyS_newuname",
- .new_func = klp_sys_newuname,
- }, { }
-};
-
-@@KLP_PATCHES_FUNCS@@;
-
static struct klp_object objs[] = {
- {
- .name = NULL, /* vmlinux */
- .funcs = vmlinux_funcs,
- },
- @@KLP_PATCHES_OBJS@@,
- { }
+ @@KLP_PATCHES_OBJS@@
};
static struct klp_patch patch = {
diff --git a/scripts/register-patches.sh b/scripts/register-patches.sh
index df611d9..47aba14 100755
--- a/scripts/register-patches.sh
+++ b/scripts/register-patches.sh
@@ -27,9 +27,12 @@
# This header must provide declarations for
# - klp_patch_SUBPATCH_init()
# - klp_patch_SUBPATCH_cleanup()
-# and an (all uppercase) KLP_PATCH_SUBPATCH_FUNCS macro.
-# The latter should be a comma separated list of KLP_PATCH*() entries,
-# each corresponding to a function the subpatch wants to replace.
+#
+# Furthermore, each subpatch must provide a SUBPATCH/patched_funcs.csv
+# file with one line of the form
+# obj old_func(,sympos) newfun
+# for every to be patched symbol.
+#
#
# Usage:
# register-patches.sh livepatch_main.c kernel-livepatch.spec
@@ -43,6 +46,7 @@ livepatch_spec_file="$2"
# Generate list of patches
declare -a livepatches
+declare -a patched_funcs
for d in *; do
[ -d "$d" ] || continue
[ x"$d" = xrpm -o x"$d" = xscripts -o x"$d" = xuname_patch ] && continue
@@ -53,7 +57,13 @@ for d in *; do
exit 1
fi
+ if [ ! -f "$d/patched_funcs.csv" ]; then
+ echo "error: $d/ doesn't have a $d/patched_funcs.csv" 1>&2
+ exit 1
+ fi
+
livepatches[${#livepatches[@]}]=$(basename $d)
+ patched_funcs[${#patched_funcs[@]}]=$(basename $d)/patched_funcs.csv
done
# Sort it
@@ -72,12 +82,57 @@ KLP_PATCHES_INCLUDES=$(
done)
## Add the individual patches' replacement entries to struct livepatch.
-KLP_PATCHES_FUNCS=$(
- echo -n "\t\t/* Auto expanded KLP_PATCHES_FUNCS: */\n"
- for p in "${livepatches[@]}"; do
- p="KLP_PATCH_$(echo $p | tr '[:lower:]' '[:upper:]')_FUNCS"
- echo -n "\t\t${p}\n"
- done | sed 's/\\n$//' # rm trailing extra newlines
+objs=
+if [ ${#patched_funcs[@]} -gt 0 ]; then
+ objs=$(cut -f1 "${patched_funcs[@]}" | grep -v '^[[:blank:]]*$' | \
+ grep -v vmlinux | sort | uniq)
+fi
+objs="vmlinux $objs"
+
+KLP_PATCHES_OBJS=$(
+ echo -n "\t/* Auto expanded KLP_PATCHES_OBJS: */\n"
+ for o in $objs; do
+ echo -n '\t{\n'
+ if [ x"$o" = xvmlinux ]; then
+ echo -n '\t\t.name = NULL,\n'
+ else
+ echo -n "\t\t.name = \"$o\",\n"
+ fi
+ echo -n '\t\t.funcs = (struct klp_func[]) {\n'
+
+ if [ x"$o" = xvmlinux ]; then
+ echo -n '\t\t\t{ .old_name = "SyS_newuname", '
+ echo -n '.new_func = klp_sys_newuname, '
+ echo -n '},\n'
+ fi
+ if [ ${#patched_funcs[@]} -gt 0 ]; then
+ sed '/^[[:blank:]]*$/ d;' "${patched_funcs[@]}" | \
+ while read _o oldfun newfun; do
+ if [ -z "$newfun" ]; then
+ echo "error: invalid patched_funcs line: " \
+ "$_o $oldfun" 1>&2
+ elif [ x"$_o" != x"$o" ]; then
+ continue
+ fi
+
+ sympos=
+ if echo $oldfun | grep -q ','; then
+ sympos=$(echo $oldfun | sed 's/[^,]\+,\(.\+\)/\1/')
+ oldfun=$(echo $oldfun | sed 's/,.*//')
+ fi
+ echo -n "\t\t\t{ .old_name = \"$oldfun\", "
+ echo -n ".new_func = $newfun, "
+ if [ -n "$sympos" ]; then
+ echo -n ".old_sympos = $sympos, "
+ fi
+ echo -n '},\n'
+ done
+ fi
+ echo -n '\t\t\t{ }\n'
+ echo -n '\t\t}\n'
+ echo -n '\t},\n'
+ done
+ printf '\t{ }\n'
)
## Initialize the individual patches in livepatch_init().
@@ -115,8 +170,7 @@ KLP_PATCHES_CLEANUP_CALLS=$(
sed -i -f - "$livepatch_main_file" <<EOF
s%@@KLP_PATCHES_INCLUDES@@%$KLP_PATCHES_INCLUDES%;
-s%\s*@@KLP_PATCHES_FUNCS@@,\?%$KLP_PATCHES_FUNCS%;
-s%\s*@@KLP_PATCHES_OBJS@@,\?%%;
+s%\s*@@KLP_PATCHES_OBJS@@,\?%$KLP_PATCHES_OBJS%;
s%\s*@@KLP_PATCHES_INIT_CALLS@@;\?%$KLP_PATCHES_INIT_CALLS%;
s%\s*@@KLP_PATCHES_INIT_ERR_HANDLERS@@:\?%$KLP_PATCHES_INIT_ERR_HANDLERS%;
s%\s*@@KLP_PATCHES_CLEANUP_CALLS@@;\?%$KLP_PATCHES_CLEANUP_CALLS%;