The klp-build script performs a sanity check on user-provided patches
using `git apply --check`.  However, this check is less strict than the
subsequent patch fixup phase, which runs `git apply --recount`.

As a result, patches with line count drift (fuzz) may pass the initial
validation but fail during fixup. Update the initial validation phase to
include the '--recount' flag.  This ensures a consistent check across
both phases and allows the script to fail fast on malformed or drifted
patches.

Signed-off-by: Joe Lawrence <[email protected]>
---
 scripts/livepatch/klp-build | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

Here are the build errors:

  $ ./scripts/livepatch/klp-build -T combined.patch 
  Validating patch(es)
  Building original kernel
  
  Copying original object files
  Fixing patch(es)
  error: patch failed: fs/proc/cmdline.c:6
  error: fs/proc/cmdline.c: patch does not apply
  error: klp-build: line 350: 'git apply "${extra_args[@]}"'
  error: klp-build: line 351: '( cd "$SRC"; sed -n '/^-- /q;p' "$patch" | git 
apply "${extra_args[@]}" )'

This was a strange one to debug, but I finally narrowed it down to
pecular `git apply` behavior depending on the presence of the --recount
flag.

Consider a patch offset by a line:

  $ cat combined.patch
  --- src.orig/fs/proc/cmdline.c        2022-10-24 15:41:08.858760066 -0400
  +++ src/fs/proc/cmdline.c     2022-10-24 15:41:11.698715352 -0400
  @@ -6,8 +6,7 @@
  
   static int cmdline_proc_show(struct seq_file *m, void *v)
   {
  -     seq_puts(m, saved_command_line);
  -     seq_putc(m, '\n');
  +     seq_printf(m, "%s livepatch=1\n", saved_command_line);
        return 0;
   }
  
  --- a/fs/proc/version.c
  +++ b/fs/proc/version.c
  @@ -9,6 +9,7 @@
  
   static int version_proc_show(struct seq_file *m, void *v)
   {
  +     seq_printf(m, "livepatch ");
        seq_printf(m, linux_proc_banner,
                utsname()->sysname,
                utsname()->release,

GNU patch reports the offset:

  $ patch --dry-run -p1 < combined.patch
  checking file fs/proc/cmdline.c
  Hunk #1 succeeded at 7 (offset 1 line).
  checking file fs/proc/version.c

It would pass the initial check as per validate_patches():

  $ git apply --check < combined.patch && echo "ok"
  ok

But later fail the patch application by refresh_patch():

  $ git apply --check --recount < combined.patch
  error: patch failed: fs/proc/cmdline.c:6
  error: fs/proc/cmdline.c: patch does not apply

Adding the same --recount argument to validate_patches() would allow the
script to fail fast and not (cryptically) way later:

  $ ./scripts/livepatch/klp-build -T combined.patch
  Validating patch(es)
  error: patch failed: fs/proc/cmdline.c:6
  error: fs/proc/cmdline.c: patch does not apply
  error: klp-build: combined.patch doesn't apply
  error: klp-build: line 453: '( cd "$SRC"; sed -n '/^-- /q;p' "$patch" | git 
apply "${extra_args[@]}" || die "$patch doesn't apply" )'

diff --git a/scripts/livepatch/klp-build b/scripts/livepatch/klp-build
index 5a8c592c4c15..2313bc909f58 100755
--- a/scripts/livepatch/klp-build
+++ b/scripts/livepatch/klp-build
@@ -379,10 +379,11 @@ revert_patch() {
 }
 
 apply_patches() {
+       local extra_args=("$@")
        local patch
 
        for patch in "${PATCHES[@]}"; do
-               apply_patch "$patch"
+               apply_patch "$patch" "${extra_args[@]}"
        done
 }
 
@@ -399,8 +400,8 @@ revert_patches() {
 
 validate_patches() {
        check_unsupported_patches
-       apply_patches
-       revert_patches
+       apply_patches --recount
+       revert_patches --recount
 }
 
 do_init() {
-- 
2.52.0


Reply via email to