#487 Add package hash checking to the buildgcc script downloaded by ./download crossgcc

Merged
and_who merged 1 commits from SolidHal/master into libreboot/master 1 year ago

+ 163 - 0
resources/libreboot/patch/crossgcc/buildgcc_hash_patch.diff

@@ -0,0 +1,163 @@
+diff --git a/util/crossgcc/buildgcc b/util/crossgcc/buildgcc
+index 97c38b8d95..d6b11ed0a6 100755
+--- a/util/crossgcc/buildgcc
++++ b/util/crossgcc/buildgcc
+@@ -270,18 +270,6 @@ check_cc() {
+ 	fi
+ }
+ 
+-check_sum() {
+-	test -z "$CHECKSUM" || \
+-	test "$(cat sum/$1.cksum 2>/dev/null | sed -e 's@.*\([0-9a-f]\{40,\}\).*@\1@')" = \
+-	"$($CHECKSUM tarballs/$1 2>/dev/null | sed -e 's@.*\([0-9a-f]\{40,\}\).*@\1@')"
+-}
+-
+-compute_sum() {
+-	test ! -f sum/$1.cksum && test -f tarballs/$1 && \
+-	(test -z "$CHECKSUM" || $CHECKSUM tarballs/$1 > sum/$1.cksum ) && \
+-	printf "(checksum created. ${RED}Note. Please upload sum/$1.cksum if the corresponding archive is upgraded.)${NC}"
+-}
+-
+ download_showing_percentage() {
+ 	url=$1
+ 	printf " ..${red}  0%%"
+@@ -293,12 +281,13 @@ download_showing_percentage() {
+ 
+ download() {
+ 	package=$1
+-	archive="$(eval echo \$$package"_ARCHIVE")"
++	archive="$package"_ARCHIVE
++	archive="${!archive}"
+ 
+ 	FILE=$(basename $archive)
+ 	printf " * $FILE "
+ 
+-	if test -f tarballs/$FILE && check_sum $FILE ; then
++	if test -f tarballs/$FILE; then
+ 		printf "(cached)"
+ 	else
+ 		printf "(downloading from $archive)"
+@@ -306,7 +295,6 @@ download() {
+ 		cd tarballs
+ 		download_showing_percentage $archive
+ 		cd ..
+-		compute_sum $FILE
+ 	fi
+ 
+ 	if [ ! -f tarballs/$FILE ]; then
+@@ -316,9 +304,100 @@ download() {
+ 	printf "\n"
+ }
+ 
++# Compute the hash of the package given in $1, and print it raw (just the
++# hexadecimal hash).
++compute_hash() {
++	package=$1
++	archive="$package"_ARCHIVE
++	archive="${!archive}"
++	file="$(basename "$archive")"
++
++	if test -z "$CHECKSUM"; then
++		echo "${RED}\$CHECKSUM program missing. This is bad.${NC}" 1>&2
++		exit 1
++	fi
++
++	$CHECKSUM "tarballs/$file" 2>/dev/null | sed -e 's@.*\([0-9a-f]\{40,\}\).*@\1@'
++}
++
++error_hash_missing() {
++	package="$1"
++	archive="$package"_ARCHIVE
++	archive="${!archive}"
++	file="$(basename "$archive")"
++
++	fullhashfile="util/crossgcc/sum/$file.cksum"
++	printf "${RED}hash file missing:${NC}\n\n" 1>&2
++	printf "Please verify util/crossgcc/tarball/$file carefully\n" 1>&2
++	printf "(using PGP if possible), and then rename\n" 1>&2
++	printf "        ${CYAN}${fullhashfile}.calc${NC}\n" 1>&2
++	printf "     to ${CYAN}${fullhashfile}${NC}\n\n" 1>&2
++
++	exit 1
++}
++
++# Read the known hash file of the package given in $1, and print it raw.
++get_known_hash() {
++	package=$1
++	archive="$package"_ARCHIVE
++	archive="${!archive}"
++	file="$(basename "$archive")"
++	hashfile="sum/$file.cksum"
++
++	if [ ! -f "$hashfile" ]; then
++		calc_hash="$(compute_hash "$package")" || exit 1
++		echo "$calc_hash  tarballs/$file" > "${hashfile}.calc"
++
++		error_hash_missing "$package"
++		exit 1
++	fi
++
++	cat "$hashfile" | sed -e 's@.*\([0-9a-f]\{40,\}\).*@\1@'
++}
++
++error_hash_mismatch() {
++	package=$1
++	known_hash="$2"
++	computed_hash="$3"
++	archive="$package"_ARCHIVE
++	archive="${!archive}"
++	file="$(basename "$archive")"
++
++	printf "${RED}hash mismatch:${NC}\n\n"
++	printf "             expected (known) hash: $known_hash\n"
++	printf "calculated hash of downloaded file: $computed_hash\n\n"
++
++	printf "If you think this is due to a network error, please delete\n"
++	printf "  ${CYAN}util/crossgcc/tarballs/$file${NC}\n"
++	printf "and try again. If the problem persists, it may be due to an\n"
++	printf "administration error on the file server, or you might be\n"
++	printf "subject to a Man-in-the-Middle attack\n\n"
++
++	exit 1
++}
++
++# verify_hash - Check that the hash of the file given in $1 matches the known
++# hash; Bail out on mismatch or missing hash file.
++verify_hash() {
++	package=$1
++	archive="$package"_ARCHIVE
++	archive="${!archive}"
++
++	known_hash="$(get_known_hash "$package")" || exit "$?"
++	computed_hash="$(compute_hash "$package")" || exit "$?"
++
++	if [ "$known_hash" != "$computed_hash" ]; then
++		error_hash_mismatch "$package" "$known_hash" "$computed_hash"
++		exit 1
++	fi
++
++	printf "${GREEN}hash verified ("$known_hash")${NC}\n"
++}
++
+ unpack_and_patch() {
+ 	package=$1
+-	archive="$(eval echo \$$package"_ARCHIVE")"
++	archive="$package"_ARCHIVE
++	archive="${!archive}"
+ 	dir="$(eval echo \$$package"_DIR")"
+ 	test -d ${dir} && test -f ${dir}/.unpack_success || (
+ 		printf " * $(basename $archive)\n"
+@@ -963,10 +1042,11 @@ export PATH=$DESTDIR$TARGETDIR/bin:$PATH
+ 
+ # Download, unpack, patch and build all packages
+ 
+-printf "Downloading tarballs ... \n"
++printf "Downloading and verifying tarballs... \n"
+ mkdir -p tarballs
+ for P in $PACKAGES; do
+-	download $P
++	  download "$P" || exit "$?"
++    verify_hash "$P" || exit "$P"
+ done
+ printf "Downloaded tarballs ... ${green}ok${NC}\n"
+ 

+ 3 - 0
resources/scripts/helpers/download/crossgcc

@@ -49,9 +49,12 @@ rm -Rf "crossgcc/"
     # workaround to fix the error on debian stretch and later, when building
     # GMP. If -pie is enabled in GCC, then --with-pic must be used when compiling
     git am ../resources/libreboot/patch/crossgcc/gccfix.diff
+    #Patch to add hash checking to buildgcc
+    git apply ../resources/libreboot/patch/crossgcc/buildgcc_hash_patch.diff
     rm -Rf .git* */*/.git*
 )
 
+
 printf "Deblobbing coreboot\n"
 ./resources/utilities/coreboot-libre/deblob