CVE-2018-1000205-2.patch 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. From 72239fc85f3eda078547956608c063ab965e90e9 Mon Sep 17 00:00:00 2001
  2. From: Teddy Reed <teddy.reed@gmail.com>
  3. Date: Sat, 9 Jun 2018 11:38:05 -0400
  4. Subject: [PATCH] vboot: Add FIT_SIGNATURE_MAX_SIZE protection
  5. This adds a new config value FIT_SIGNATURE_MAX_SIZE, which controls the
  6. max size of a FIT header's totalsize field. The field is checked before
  7. signature checks are applied to protect from reading past the intended
  8. FIT regions.
  9. This field is not part of the vboot signature so it should be sanity
  10. checked. If the field is corrupted then the structure or string region
  11. reads may have unintended behavior, such as reading from device memory.
  12. A default value of 256MB is set and intended to support most max storage
  13. sizes.
  14. Suggested-by: Simon Glass <sjg@chromium.org>
  15. Signed-off-by: Teddy Reed <teddy.reed@gmail.com>
  16. Reviewed-by: Simon Glass <sjg@chromium.org>
  17. Upstream-Status: Backport[http://git.denx.de/?p=u-boot.git;a=commit;
  18. h=72239fc85f3eda078547956608c063ab965e90e9]
  19. CVE: CVE-2018-1000205
  20. Signed-off-by: Changqing Li <changqing.li@windriver.com>
  21. ---
  22. Kconfig | 10 ++++++++++
  23. common/image-sig.c | 5 +++++
  24. test/py/tests/test_vboot.py | 33 +++++++++++++++++++++++++++++++++
  25. tools/Makefile | 1 +
  26. 4 files changed, 49 insertions(+)
  27. diff --git a/Kconfig b/Kconfig
  28. index 5a82c95..c8b86cd 100644
  29. --- a/Kconfig
  30. +++ b/Kconfig
  31. @@ -267,6 +267,16 @@ config FIT_SIGNATURE
  32. format support in this case, enable it using
  33. CONFIG_IMAGE_FORMAT_LEGACY.
  34. +config FIT_SIGNATURE_MAX_SIZE
  35. + hex "Max size of signed FIT structures"
  36. + depends on FIT_SIGNATURE
  37. + default 0x10000000
  38. + help
  39. + This option sets a max size in bytes for verified FIT uImages.
  40. + A sane value of 256MB protects corrupted DTB structures from overlapping
  41. + device memory. Assure this size does not extend past expected storage
  42. + space.
  43. +
  44. config FIT_VERBOSE
  45. bool "Show verbose messages when FIT images fail"
  46. help
  47. diff --git a/common/image-sig.c b/common/image-sig.c
  48. index f65d883..8d2fd10 100644
  49. --- a/common/image-sig.c
  50. +++ b/common/image-sig.c
  51. @@ -156,6 +156,11 @@ static int fit_image_setup_verify(struct image_sign_info *info,
  52. {
  53. char *algo_name;
  54. + if (fdt_totalsize(fit) > CONFIG_FIT_SIGNATURE_MAX_SIZE) {
  55. + *err_msgp = "Total size too large";
  56. + return 1;
  57. + }
  58. +
  59. if (fit_image_hash_get_algo(fit, noffset, &algo_name)) {
  60. *err_msgp = "Can't get hash algo property";
  61. return -1;
  62. diff --git a/test/py/tests/test_vboot.py b/test/py/tests/test_vboot.py
  63. index ee939f2..3d25ec3 100644
  64. --- a/test/py/tests/test_vboot.py
  65. +++ b/test/py/tests/test_vboot.py
  66. @@ -26,6 +26,7 @@ Tests run with both SHA1 and SHA256 hashing.
  67. import pytest
  68. import sys
  69. +import struct
  70. import u_boot_utils as util
  71. @pytest.mark.boardspec('sandbox')
  72. @@ -105,6 +106,26 @@ def test_vboot(u_boot_console):
  73. util.run_and_log(cons, [mkimage, '-F', '-k', tmpdir, '-K', dtb,
  74. '-r', fit])
  75. + def replace_fit_totalsize(size):
  76. + """Replace FIT header's totalsize with something greater.
  77. +
  78. + The totalsize must be less than or equal to FIT_SIGNATURE_MAX_SIZE.
  79. + If the size is greater, the signature verification should return false.
  80. +
  81. + Args:
  82. + size: The new totalsize of the header
  83. +
  84. + Returns:
  85. + prev_size: The previous totalsize read from the header
  86. + """
  87. + total_size = 0
  88. + with open(fit, 'r+b') as handle:
  89. + handle.seek(4)
  90. + total_size = handle.read(4)
  91. + handle.seek(4)
  92. + handle.write(struct.pack(">I", size))
  93. + return struct.unpack(">I", total_size)[0]
  94. +
  95. def test_with_algo(sha_algo):
  96. """Test verified boot with the given hash algorithm.
  97. @@ -146,6 +167,18 @@ def test_vboot(u_boot_console):
  98. util.run_and_log(cons, [fit_check_sign, '-f', fit, '-k', tmpdir,
  99. '-k', dtb])
  100. + # Replace header bytes
  101. + bcfg = u_boot_console.config.buildconfig
  102. + max_size = int(bcfg.get('config_fit_signature_max_size', 0x10000000), 0)
  103. + existing_size = replace_fit_totalsize(max_size + 1)
  104. + run_bootm(sha_algo, 'Signed config with bad hash', 'Bad Data Hash', False)
  105. + cons.log.action('%s: Check overflowed FIT header totalsize' % sha_algo)
  106. +
  107. + # Replace with existing header bytes
  108. + replace_fit_totalsize(existing_size)
  109. + run_bootm(sha_algo, 'signed config', 'dev+', True)
  110. + cons.log.action('%s: Check default FIT header totalsize' % sha_algo)
  111. +
  112. # Increment the first byte of the signature, which should cause failure
  113. sig = util.run_and_log(cons, 'fdtget -t bx %s %s value' %
  114. (fit, sig_node))
  115. diff --git a/tools/Makefile b/tools/Makefile
  116. index 5dd33ed..0c3341e 100644
  117. --- a/tools/Makefile
  118. +++ b/tools/Makefile
  119. @@ -133,6 +133,7 @@ ifdef CONFIG_FIT_SIGNATURE
  120. # This affects include/image.h, but including the board config file
  121. # is tricky, so manually define this options here.
  122. HOST_EXTRACFLAGS += -DCONFIG_FIT_SIGNATURE
  123. +HOST_EXTRACFLAGS += -DCONFIG_FIT_SIGNATURE_MAX_SIZE=$(CONFIG_FIT_SIGNATURE_MAX_SIZE)
  124. endif
  125. ifdef CONFIG_SYS_U_BOOT_OFFS
  126. --
  127. 2.7.4