Add script to enable IBPB on COS VMs.

`retbleed=ibpb` will fully mitigate the Inception vulnerability in AMD
processors after microcode updates are applied. Users can use this
script to choose to apply this mitigation.

`retbleed=ibpb` has a substantial performance penalty; in our
experience, it is by far the worst out of all speculative execution
vulnerability mitigations (~50%, up to ~80% in one benchmark).

There is still uncertainty in whether an alternative mitigation will be
sent to Linux mailing lists or not.

References:
- https://www.amd.com/en/resources/product-security/bulletin/amd-sb-7005.html
- https://comsec.ethz.ch/research/microarch/inception/

BUG=b/295020291
TEST=Create N2D VM with this script in startup-script metadata; ssh in
and check /sys/devices/system/cpu/vulnerabilities/retbleed

Change-Id: Icf044c43c28a1222d0f511c475e85654dd3f794b
Reviewed-on: https://cos-review.googlesource.com/c/cos/tools/+/54167
Cloud-Build: GCB Service account <228075978874@cloudbuild.gserviceaccount.com>
Tested-by: Robert Kolchmeyer <rkolchmeyer@google.com>
Reviewed-by: Oleksandr Tymoshenko <ovt@google.com>
diff --git a/src/scripts/enable_ibpb.sh b/src/scripts/enable_ibpb.sh
new file mode 100644
index 0000000..3d6a680
--- /dev/null
+++ b/src/scripts/enable_ibpb.sh
@@ -0,0 +1,62 @@
+# Copyright 2023 Google LLC
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Run this script to enable IBPB mitigations on COS VMs. Secure boot must be
+# disabled.
+#
+# WARNING: While this mitigation will improve the security of your nodes, it is
+# known to have a _dramatic_ performance impact on some workloads - on the order
+# of ~50% worse performance on AMD processors. Be careful when deploying this
+# script.
+
+set -o errexit
+set -o pipefail
+set -o nounset
+
+function check_not_secure_boot() {
+  if [[ ! -d "/sys/firmware/efi" ]]; then
+    return
+  fi
+  efi="$(mktemp -d)"
+  mount -t efivarfs none "${efi}"
+  secure_boot="$(cat "${efi}"/SecureBoot-* | python -c 'import sys; print(sys.stdin.buffer.read() == b"\x06\x00\x00\x00\x01")')"
+  umount "${efi}"
+  rmdir "${efi}"
+  if [[ "${secure_boot}" == "True" ]]; then
+    echo "Secure Boot is enabled. Boot options cannot be changed. You must disable secure boot to enable IBPB mitigations."
+    exit 1
+  fi
+}
+
+function main() {
+  if grep " retbleed=ibpb " /proc/cmdline > /dev/null; then
+    echo "'retbleed=ibpb' already present on the kernel command line. Nothing to do."
+    return
+  fi
+  echo "Attempting to set 'retbleed=ibpb' on the kernel command line."
+  if [[ "${EUID}" -ne 0 ]]; then
+    echo "This script must be run as root."
+    return 1
+  fi
+  check_not_secure_boot
+
+  dir="$(mktemp -d)"
+  mount /dev/disk/by-partlabel/EFI-SYSTEM "${dir}"
+  sed -i -e "s|cros_efi|cros_efi retbleed=ibpb|g" "${dir}/efi/boot/grub.cfg"
+  umount "${dir}"
+  rmdir "${dir}"
+  echo "Rebooting."
+  reboot
+}
+
+main