0ac0effe14
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
139 lines
4.7 KiB
Diff
139 lines
4.7 KiB
Diff
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
|
|
|