futility/updater: Ignore preserve_me quirks for non-host programmers.

The preserve_me quirk allows avoiding modifying the ME region while it
may be running. Its apply function attempts to skip itself when not
flashing the OS-bundled firmware by checking for whether an archive is
set, but this doesn't work since in the absence of an actual archive
file, a filesystem archive implementation is used instead.

While flashing over a non-host programmer the ME is not running and
therefore it is safe to update the ME region.

Add unit test cases for the preserve_me quirk applying successfully when
using the default host programmer and being skipped when using another
programmer.

BUG=b:213706510
TEST=futility update -p dummy... with preserve_me quirk skips the quirk;
     chromeos-firmwareupdate with a preserve_me quirk applies the quirk
BRANCH=none

Change-Id: Ie5578c9b3cf7eba55626bb931589bf360fe28269
Signed-off-by: Sam McNally <sammc@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/vboot_reference/+/3450060
Reviewed-by: Edward O'Callaghan <quasisec@chromium.org>
diff --git a/futility/updater.c b/futility/updater.c
index 4d96d2f..4c650b2 100644
--- a/futility/updater.c
+++ b/futility/updater.c
@@ -531,11 +531,16 @@
 				image_from, image_to, FMAP_SI_DESC);
 	}
 
-	if (try_apply_quirk(QUIRK_PRESERVE_ME, cfg) > 0) {
-		VB2_DEBUG("ME needs to be preserved - preserving %s.\n",
-			  FMAP_SI_ME);
-		return preserve_firmware_section(
-				image_from, image_to, FMAP_SI_ME);
+	if (!strcmp(image_from->programmer, PROG_HOST)) {
+		if (try_apply_quirk(QUIRK_PRESERVE_ME, cfg) > 0) {
+			VB2_DEBUG("ME needs to be preserved - preserving %s.\n",
+				  FMAP_SI_ME);
+			return preserve_firmware_section(image_from, image_to,
+							 FMAP_SI_ME);
+		}
+	} else {
+		VB2_DEBUG("Flashing via non-host programmer %s - no need to "
+			  "preserve ME.\n", image_from->programmer);
 	}
 
 	return try_apply_quirk(QUIRK_UNLOCK_ME_FOR_UPDATE, cfg);
diff --git a/tests/futility/test_update.sh b/tests/futility/test_update.sh
index d2ab028..25c5543 100755
--- a/tests/futility/test_update.sh
+++ b/tests/futility/test_update.sh
@@ -141,6 +141,9 @@
 cp -f "${TMP}.expected.full" "${TMP}.expected.me_unlocked"
 patch_file "${TMP}.expected.me_unlocked" SI_DESC 128 \
 	"\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff"
+cp -f "${TMP}.expected.full" "${TMP}.expected.me_preserved"
+"${FUTILITY}" load_fmap "${TMP}.expected.me_preserved" \
+	"SI_ME:${TMP}.from/SI_ME"
 
 # A special set of images that only RO_VPD is preserved (RW_VPD is wiped) using
 # FMAP_AREA_PRESERVE (\010=0x08).
@@ -357,6 +360,17 @@
 	--quirks no_check_platform \
 	-i "${TO_IMAGE}" --wp=0 --sys_props 0,0x10001,1
 
+test_update "Full update (--quirks preserve_me with non-host programmer)" \
+	"${FROM_IMAGE}" "${TMP}.expected.full" \
+	--quirks preserve_me \
+	-i "${TO_IMAGE}" --wp=0 --sys_props 0,0x10001,1 \
+	-p raiden_debug_spi:target=AP
+
+test_update "Full update (--quirks preserve_me)" \
+	"${FROM_IMAGE}" "${TMP}.expected.me_preserved" \
+	--quirks preserve_me \
+	-i "${TO_IMAGE}" --wp=0 --sys_props 0,0x10001,1
+
 # Test archive and manifest.
 A="${TMP}.archive"
 mkdir -p "${A}/bin"