Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support to verify reboot for secure boot #979

Merged
merged 14 commits into from
Jul 13, 2020
10 changes: 6 additions & 4 deletions scripts/fast-reboot
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ EXIT_SYNCD_SHUTDOWN=11
EXIT_FAST_REBOOT_DUMP_FAILURE=12
EXIT_FILTER_FDB_ENTRIES_FAILURE=13
EXIT_NO_CONTROL_PLANE_ASSISTANT=20
EXIT_SONIC_INSTALLER_VERIFY_REBOOT=21

function error()
{
Expand Down Expand Up @@ -305,10 +306,11 @@ function reboot_pre_check()
exit ${EXIT_FILE_SYSTEM_FULL}
fi

# Make sure that the next image exists
if [[ ! -d ${IMAGE_PATH} ]]; then
debug "Next image ${NEXT_SONIC_IMAGE} doesn't exist ..."
exit ${EXIT_NEXT_IMAGE_NOT_EXISTS}
# Verify the next image by sonic_installer
local message=$(sonic_installer verify_next_image 2>&1)
if [ $? -ne 0 ]; then
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This part of the reboot script is executed under -e option, meaning that the failure will trigger script to exit. Please take examples in the script to catch error code.

Copy link
Collaborator Author

@xumia xumia Jul 11, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, the command can be simplified, fixed. #Closed

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you simplified this way, the sonic_installer verify-next-image will only output Failed or Done, which has no context in fast-reboot output.

As Ying suggested: Please take examples in the script to catch error code.

Your original debug command is still useful.


In reply to: 453135626 [](ancestors = 453135626)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks Qi, fixed.

Copy link
Contributor

@qiluo-msft qiluo-msft Jul 12, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @yxieca actually #Closed

debug "Failed to verify next image by running command: sonic_installer verify_next_image, result message: ${message}"
jleveque marked this conversation as resolved.
Show resolved Hide resolved
exit ${EXIT_SONIC_INSTALLER_VERIFY_REBOOT}
fi

# Make sure ASIC configuration has not changed between images
Expand Down
10 changes: 6 additions & 4 deletions scripts/reboot
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ PLAT_REBOOT="platform_reboot"
REBOOT_CAUSE_FILE="/host/reboot-cause/reboot-cause.txt"
VERBOSE=no
EXIT_NEXT_IMAGE_NOT_EXISTS=4
EXIT_SONIC_INSTALLER_VERIFY_REBOOT=21

function debug()
{
Expand Down Expand Up @@ -79,10 +80,11 @@ function reboot_pre_check()
fi
rm ${filename}

# Make sure that the next image exists
if [[ ! -d ${IMAGE_PATH} ]]; then
VERBOSE=yes debug "Next image ${NEXT_SONIC_IMAGE} doesn't exist ..."
exit ${EXIT_NEXT_IMAGE_NOT_EXISTS}
# Verify the next image by sonic_installer
local message=$(sonic_installer verify_next_image 2>&1)
if [ $? -ne 0 ]; then
VERBOSE=yes debug "Failed to verify the next image by running command: sonic_installer verify_next_image, result message: ${message}"
jleveque marked this conversation as resolved.
Show resolved Hide resolved
exit ${EXIT_SONIC_INSTALLER_VERIFY_REBOOT}
fi
}

Expand Down
12 changes: 10 additions & 2 deletions sonic_installer/bootloader/aboot.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
from .bootloader import Bootloader

_secureboot = None
DEFAULT_SWI_IMAGE = 'sonic.swi'

# For the signature format, see: https://github.com/aristanetworks/swi-tools/tree/master/switools
SWI_SIG_FILE_NAME = 'swi-signature'
Expand Down Expand Up @@ -110,9 +111,9 @@ def remove_image(self, image):
self._boot_config_set(SWI=image_path, SWI_DEFAULT=image_path)
click.echo("Set next and default boot to current image %s" % current)

image_dir = image.replace(IMAGE_PREFIX, IMAGE_DIR_PREFIX)
image_path = self.get_image_path(image)
click.echo('Removing image root filesystem...')
subprocess.call(['rm','-rf', os.path.join(HOST_PATH, image_dir)])
subprocess.call(['rm','-rf', image_path])
click.echo('Image removed')

def get_binary_image_version(self, image_path):
Expand All @@ -129,6 +130,13 @@ def verify_binary_image(self, image_path):
except subprocess.CalledProcessError:
return False

def verify_next_image(self):
if not super(AbootBootloader, self).verify_next_image():
return False
image = self.get_next_image()
image_path = os.path.join(self.get_image_path(image), DEFAULT_SWI_IMAGE)
return self._verify_secureboot_image(image_path)

def _verify_secureboot_image(self, image_path):
if isSecureboot():
cert = self.getCert(image_path)
Expand Down
24 changes: 24 additions & 0 deletions sonic_installer/bootloader/bootloader.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,15 @@
Abstract Bootloader class
"""

import sys
from os import path

from ..common import (
HOST_PATH,
IMAGE_DIR_PREFIX,
IMAGE_PREFIX,
)

class Bootloader(object):

NAME = None
Expand Down Expand Up @@ -43,8 +52,23 @@ def verify_binary_image(self, image_path):
"""verify that the image is supported by the bootloader"""
raise NotImplementedError

def verify_next_image(self):
"""verify the next image for reboot"""
image = self.get_next_image()
jleveque marked this conversation as resolved.
Show resolved Hide resolved
image_path = self.get_image_path(image)
if not path.exists(image_path):
sys.stderr.write('Next image {0} doesn\'t exist ...\n'.format(image))
jleveque marked this conversation as resolved.
Show resolved Hide resolved
return False
return True

@classmethod
def detect(cls):
"""returns True if the bootloader is in use"""
return False

@classmethod
def get_image_path(cls, image):
"""returns the image path"""
prefix = path.join(HOST_PATH, IMAGE_DIR_PREFIX)
return image.replace(IMAGE_PREFIX, prefix)

10 changes: 10 additions & 0 deletions sonic_installer/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -476,5 +476,15 @@ def rollback_docker(container_name):

click.echo('Done')

# verify the next image
@cli.command('verify_next_image')
def verify_reboot():
jleveque marked this conversation as resolved.
Show resolved Hide resolved
""" Verify the next image for reboot"""
bootloader = get_bootloader()
if not bootloader.verify_next_image():
click.echo('Failed')
jleveque marked this conversation as resolved.
Show resolved Hide resolved
sys.exit(1)
click.echo('Done')
jleveque marked this conversation as resolved.
Show resolved Hide resolved

if __name__ == '__main__':
cli()