Debian: kpatch: support the signature for livepatch module

Add the support for the signature of livepatched modules, so we can
avoid the unsigned kernel module loading issue.

Test Plan:
Pass: Verify the kpatch-build building process.
Pass: Execute shellcheck tool without errors and warnings for
      the kpatch-build script after applying this patch.

Story: 2009221
Task: 44580

Signed-off-by: Zhixiong Chi <zhixiong.chi@windriver.com>
Change-Id: Ieb56539b873dab3eab350797b8c3ab2d8923ef5d
This commit is contained in:
Zhixiong Chi 2022-05-05 03:06:18 -07:00
parent b33187d154
commit 0ac0effe14
2 changed files with 139 additions and 0 deletions

View File

@ -0,0 +1,138 @@
From 92337a56eaee72228a73846a65660cae1c98cc88 Mon Sep 17 00:00:00 2001
From: Zhixiong Chi <zhixiong.chi@windriver.com>
Date: Thu, 5 May 2022 02:41:42 -0700
Subject: [PATCH] kpatch: Add the signature for livepatch kernel modules
As the commit [https://review.opendev.org/c/starlingx/kernel/+/838284]
shows, once lockdown feature for secure boot was enabled, the unsigned
kernel modules' loading will fail with the error 'Operation not permitted'.
For livepatched kernel module we also need to sign the module so that we
can insmod the module successfully when the command 'kpatch load xxx.ko'
or 'systemctl start kpatch.service' is executed.
Add '-k/--keydir' to support the customzied pubkey/privkey pairs.
Drop some unused variables for starlingx platform.
Signed-off-by: Zhixiong Chi <zhixiong.chi@windriver.com>
---
kpatch-build/kpatch-build | 54 ++++++++++++++++++++++++++-------------
1 file changed, 36 insertions(+), 18 deletions(-)
diff --git a/kpatch-build/kpatch-build b/kpatch-build/kpatch-build
index 3c721ea..8a9fa03 100755
--- a/kpatch-build/kpatch-build
+++ b/kpatch-build/kpatch-build
@@ -49,6 +49,11 @@ ENVFILE="$TEMPDIR/kpatch-build.env"
LOGFILE="$CACHEDIR/build.log"
RELEASE_FILE=/etc/os-release
LINUXSRCDIR=/usr/src
+KVERSION=$(uname -r)
+KEYDIR="${LINUXSRCDIR}/kernels/${KVERSION}"
+SIGNTOOLDIR=(/usr/lib/linux*-kbuild-*/scripts)
+SIGNTOOL="sign-file"
+SIGHASH="sha256"
DEBUG=0
SKIPCLEANUP=0
SKIPCOMPILERCHECK=0
@@ -523,6 +528,19 @@ module_name_string() {
echo "${1//[^a-zA-Z0-9_-]/-}" | cut -c 1-48
}
+# Sign the generated livepatched kernel module
+sign_module() {
+ local module=${1}
+ PRIVKEY="${KEYDIR}/signing_key.pem"
+ PUBKEY="${KEYDIR}/signing_key.x509"
+ SIGNTOOL_ABSPATH=$(find "${SIGNTOOLDIR[@]}" -name "${SIGNTOOL}")
+ [[ ! -e "${SIGNTOOL_ABSPATH}" ]] && die "can't find ${SIGNTOOL}."
+ [[ ! -e "${PRIVKEY}" ]] && die "can't find privkey ${PRIVKEY}."
+ [[ ! -e "${PUBKEY}" ]] && die "can't find publickey ${PUBKEY}."
+
+ "${SIGNTOOL_ABSPATH}" "${SIGHASH}" "${PRIVKEY}" "${PUBKEY}" "${module}" || die "Sign module ${module} failed!"
+}
+
usage() {
echo "usage: $(basename "$0") [options] <patch1 ... patchN>" >&2
echo " patchN Input patchfile(s)" >&2
@@ -547,7 +565,7 @@ usage() {
echo " (not recommended)" >&2
}
-options="$(getopt -o ha:r:s:c:v:j:t:n:o:de:R -l "help,archversion:,sourcerpm:,sourcedir:,config:,vmlinux:,jobs:,target:,name:,output:,oot-module:,debug,skip-gcc-check,skip-compiler-check,skip-cleanup,non-replace" -- "$@")" || die "getopt failed"
+options="$(getopt -o ha:r:s:c:v:j:t:n:o:k:de:R -l "help,archversion:,sourcerpm:,sourcedir:,config:,vmlinux:,jobs:,target:,name:,output:,keydir:,oot-module:,debug,skip-gcc-check,skip-compiler-check,skip-cleanup,non-replace" -- "$@")" || die "getopt failed"
eval set -- "$options"
@@ -599,6 +617,11 @@ while [[ $# -gt 0 ]]; do
BASE="$(readlink -f "$2")"
shift
;;
+ -k|--keydir)
+ [[ ! -d "$2" ]] && die "keydir '$2' not found"
+ KEYDIR="$(readlink -f "$2")"
+ shift
+ ;;
-d|--debug)
DEBUG=$((DEBUG + 1))
if [[ $DEBUG -eq 1 ]]; then
@@ -785,22 +808,7 @@ else
echo "Debian/Ubuntu distribution detected"
- if [[ "$DISTRO" = ubuntu ]]; then
-
- # url may be changed for a different mirror
- url="http://archive.ubuntu.com/ubuntu/pool/main/l"
- sublevel="SUBLEVEL = 0"
-
- elif [[ "$DISTRO" = debian ]]; then
-
- # url may be changed for a different mirror
- url="http://ftp.debian.org/debian/pool/main/l"
- sublevel="SUBLEVEL = 0"
- fi
-
- pkgname="$(dpkg-query -W -f='${Source}' "linux-image-$ARCHVERSION" | sed s/-signed//)"
- pkgver="$(dpkg-query -W -f='${Version}' "linux-image-$ARCHVERSION")"
- dscname="${pkgname}_${pkgver}.dsc"
+ sublevel="SUBLEVEL = 0"
clean_cache
@@ -815,7 +823,7 @@ else
KSRCVER="${KVER%.*}"
KSRCNAME="$LINUXSRCDIR/linux-source-$KSRCVER.tar.xz"
if [[ -e "$KSRCNAME" ]]; then
- tar xvf $KSRCNAME
+ tar xvf "${KSRCNAME}" 2>&1 | logger || die
mv "linux-source-$KSRCVER" "$SRCDIR" || die
fi
# Due to the ostree mechanism, we need add the prefix for kernel config here
@@ -977,6 +985,14 @@ else
MAKEVARS+=("LD=${KPATCH_CC_PREFIX}ld")
fi
+# Adjust the kconfig
+KCONFIGACK=""
+KCONFIGCOUNT=$(make listnewconfig | wc -l)
+while [[ "${KCONFIGCOUNT}" -gt 0 ]]; do
+ KCONFIGACK=${KCONFIGACK}"\n"
+ let KCONFIGCOUNT--
+done
+echo -e "${KCONFIGACK}" | make -f ./Makefile syncconfig 2>&1 | logger || die
# $TARGETS used as list, no quotes.
# shellcheck disable=SC2086
@@ -1257,6 +1273,8 @@ UNDEFINED=$(comm -23 <(sort -u "${TEMPDIR}"/undefined_references) \
cp -f "$TEMPDIR/patch/$MODNAME.ko" "$BASE" || die
+sign_module "${BASE}/${MODNAME}.ko" | logger
+
[[ "$DEBUG" -eq 0 && "$SKIPCLEANUP" -eq 0 ]] && rm -f "$LOGFILE"
echo "SUCCESS"
--
2.34.1

View File

@ -1 +1,2 @@
0001-kpatch-Support-for-WRCP.patch
0002-kpatch-Add-the-signature-for-livepatch-kernel-module.patch