1#!/usr/bin/env python3

2# Copyright 2019 Canonical Ltd.

3# All rights reserved.

4#

5# Written by:

6# Jonathan Cave <jonathan.cave@canonical.com>

7

8 import hashlib

9 import os

10 import sys

11

12 from checkbox_support.snap_utils.system import get_kernel_snap

13 from checkbox_support.snap_utils.system import get_series

14 from checkbox_support.snap_utils.system import add_hostfs_prefix

15

16# 64kb buffer, hopefully suitable for all devices that might run this test

17 BUF_SIZE = 65536

18

19

20 def get_snap_kernel_path():

21 kernel = get_kernel_snap()

22 if kernel is None:

23 raise SystemExit("ERROR: failed to get kernel snap")

24 if int(get_series()) >= 20:

25 path = "/snap/{}/current/kernel.efi".format(kernel)

26 else:

27 path = "/snap/{}/current/kernel.img".format(kernel)

28 return path

29

30

31 def get_hash(path):

32 sha1 = hashlib.sha1()

33 with open(path, "rb") as f:

34 while True:

35 data = f.read(BUF_SIZE)

36 if not data:

37 break

38 sha1.update(data)

39 return sha1.hexdigest()

40

41

42 def kernel_matches_current(booted_kernel_image):

43 rh = get_hash(booted_kernel_image)

44 print("Running kernel hash:\n", rh, "\n")

45 snap_kernel_image = get_snap_kernel_path()

46 print("Snap kernel image: {}".format(snap_kernel_image))

47 sh = get_hash(snap_kernel_image)

48 print("Current kernel snap hash:\n", sh, "\n")

49 if rh != sh:

50 print("ERROR: hashes do not match")

51 return 1

52 print("Hashes match")

53 return 0

54

55

56 if __name__ == "__main__":

57 if len(sys.argv) != 2:

58 raise SystemExit("ERROR: please specify the path to booted kernel")

59 booted_kernel_image = sys.argv[1]

60

61 print("Supplied booted kernel image: {}".format(booted_kernel_image))

62 prefixed_image = add_hostfs_prefix(booted_kernel_image)

63

64 if not os.path.exists(prefixed_image):

65 raise SystemExit("ERROR: invalid path to booted kernel supplied")

66

67 sys.exit(kernel_matches_current(prefixed_image))