From cd27fa521cf56aaca72643aab67d4fda62b78c6d Mon Sep 17 00:00:00 2001
From: Andy Whitcroft <apw@canonical.com>
Date: Wed, 24 Jan 2018 21:54:56 +0000
Subject: [PATCH 087/131] UBUNTU: [Packaging] retpoline -- add call site
 validation

CVE-2017-5715 (Spectre v2 retpoline)

Signed-off-by: Andy Whitcroft <apw@canonical.com>
---
 debian/rules.d/0-common-vars.mk  |  1 +
 debian/rules.d/2-binary-arch.mk  |  2 ++
 debian/rules.d/4-checks.mk       | 15 +++++++++++++-
 debian/scripts/retpoline-check   | 42 ++++++++++++++++++++++++++++++++++++++++
 debian/scripts/retpoline-extract | 13 +++++++++++++
 5 files changed, 72 insertions(+), 1 deletion(-)
 create mode 100755 debian/scripts/retpoline-check
 create mode 100755 debian/scripts/retpoline-extract

diff --git a/debian/rules.d/0-common-vars.mk b/debian/rules.d/0-common-vars.mk
index d06de00c3e8c..26b928ac862b 100644
--- a/debian/rules.d/0-common-vars.mk
+++ b/debian/rules.d/0-common-vars.mk
@@ -27,6 +27,7 @@ AUTOBUILD=
 ifneq ($(AUTOBUILD),)
 skipabi		= true
 skipmodule	= true
+skipretpoline	= true
 skipdbg		= true
 gitver=$(shell if test -f .git/HEAD; then cat .git/HEAD; else uuidgen; fi)
 gitverpre=$(shell echo $(gitver) | cut -b -3)
diff --git a/debian/rules.d/2-binary-arch.mk b/debian/rules.d/2-binary-arch.mk
index 0e2656ec61db..035378d77346 100644
--- a/debian/rules.d/2-binary-arch.mk
+++ b/debian/rules.d/2-binary-arch.mk
@@ -102,6 +102,8 @@ endif
 		$(pkgdir)/boot/config-$(abi_release)-$*
 	install -m644 $(abidir)/$* \
 		$(pkgdir)/boot/abi-$(abi_release)-$*
+	install -m644 $(abidir)/$*.retpoline \
+		$(pkgdir)/boot/retpoline-$(abi_release)-$*
 	install -m600 $(builddir)/build-$*/System.map \
 		$(pkgdir)/boot/System.map-$(abi_release)-$*
 	if [ "$(dtb_files)" ]; then \
diff --git a/debian/rules.d/4-checks.mk b/debian/rules.d/4-checks.mk
index a3c8ed98330d..96ffbe75480f 100644
--- a/debian/rules.d/4-checks.mk
+++ b/debian/rules.d/4-checks.mk
@@ -16,7 +16,20 @@ module-check-%: $(stampdir)/stamp-build-%
 	@perl -f $(DROOT)/scripts/module-check "$*" \
 		"$(prev_abidir)" "$(abidir)" $(skipmodule)
 
-checks-%: module-check-% abi-check-%
+# Check the reptoline jmp/call functions against the last release.
+retpoline-check-%: $(stampdir)/stamp-build-%
+	@echo Debug: $@
+	install -d $(abidir)
+	if grep -q CONFIG_RETPOLINE=y $(builddir)/build-$*/.config; then \
+		$(SHELL) $(DROOT)/scripts/retpoline-extract $(builddir)/build-$* \
+			>$(abidir)/$*.retpoline; \
+	else \
+		echo "# RETPOLINE NOT ENABLED" >$(abidir)/$*.retpoline; \
+	fi
+	$(SHELL) $(DROOT)/scripts/retpoline-check "$*" \
+		"$(prev_abidir)" "$(abidir)" "$(skipretpoline)"
+
+checks-%: module-check-% abi-check-% retpoline-check-%
 	@echo Debug: $@
 
 # Check the config against the known options list.
diff --git a/debian/scripts/retpoline-check b/debian/scripts/retpoline-check
new file mode 100755
index 000000000000..b7d5e903fe2c
--- /dev/null
+++ b/debian/scripts/retpoline-check
@@ -0,0 +1,42 @@
+#!/bin/bash
+
+flavour="$1"
+prev_abidir="$2"
+curr_abidir="$3"
+skipretpoline="$4"
+
+echo "II: Checking retpoline indirections for $flavour...";
+
+if [ "$skipretpoline" = 'true' ]; then
+	echo "manual request ignoring retpoline delta"
+fi
+
+if [ -f "$prev_abidir/ignore.retpoline" -o \
+     -f "$prev_abidir/$flavour.ignore.retpoline" ]; then
+	echo "explicitly ignoring retpoline delta"
+	skipretpoline='true'
+fi
+
+prev="$prev_abidir/$flavour.retpoline"
+curr="$curr_abidir/$flavour.retpoline"
+if [ ! -f "$prev" ]; then
+	echo "previous retpoline file missing!"
+	echo "   $prev"
+	prev="/dev/null"
+fi
+if [ ! -f "$curr" ]; then
+	echo "current retpoline file missing!"
+	echo "   $curr"
+	curr="/dev/null"
+fi
+
+echo "II: retpoline delta in this package..."
+rc=0
+diff -u "$prev" "$curr" || rc=1
+
+echo "II: Done";
+if [ "$skipretpoline" = 'true' -a "$rc" -ne 0 ]; then
+	echo "II: ignoring errors"
+	exit 0
+fi
+exit "$rc"
diff --git a/debian/scripts/retpoline-extract b/debian/scripts/retpoline-extract
new file mode 100755
index 000000000000..c401f2f72354
--- /dev/null
+++ b/debian/scripts/retpoline-extract
@@ -0,0 +1,13 @@
+#!/bin/bash
+
+cd "$1" || exit 1
+
+{
+	echo "./vmlinux"
+	find . -name \*.ko
+} | xargs objdump --disassemble | \
+awk -F'	' '
+	/^.\//				{ file=$1; sub(":.*", "", file); sub("^.*/", "", file); }
+	/^[0-9a-f][0-9a-f]* <.*>:/	{ tag=$1; sub(".*<", "", tag); sub(">.*", "", tag); tag=file " " tag; }
+	$3 ~ /(callq|jmpq)  *\*%/	{ print(tag " " $3); }
+'
-- 
2.15.1

