misc.c 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332
  1. /*
  2. * Copyright 2014 The Chromium OS Authors. All rights reserved.
  3. * Use of this source code is governed by a BSD-style license that can be
  4. * found in the LICENSE file.
  5. */
  6. #include <errno.h>
  7. #ifndef HAVE_MACOS
  8. #include <linux/fs.h> /* For BLKGETSIZE64 */
  9. #endif
  10. #include <stdarg.h>
  11. #include <stdint.h>
  12. #include <stdio.h>
  13. #include <stdlib.h>
  14. #include <string.h>
  15. #include <sys/ioctl.h>
  16. #include <sys/mman.h>
  17. #include <sys/stat.h>
  18. #include <sys/types.h>
  19. #include <sys/wait.h>
  20. #include <unistd.h>
  21. #include "2sysincludes.h"
  22. #include "2common.h"
  23. #include "2sha.h"
  24. #include "cgptlib_internal.h"
  25. #include "file_type.h"
  26. #include "futility.h"
  27. #include "gbb_header.h"
  28. /* Default is to support everything we can */
  29. enum vboot_version vboot_version = VBOOT_VERSION_ALL;
  30. int debugging_enabled;
  31. void Debug(const char *format, ...)
  32. {
  33. if (!debugging_enabled)
  34. return;
  35. va_list ap;
  36. va_start(ap, format);
  37. fprintf(stdout, "DEBUG: ");
  38. vfprintf(stdout, format, ap);
  39. va_end(ap);
  40. }
  41. static int is_null_terminated(const char *s, int len)
  42. {
  43. len--;
  44. s += len;
  45. while (len-- >= 0)
  46. if (!*s--)
  47. return 1;
  48. return 0;
  49. }
  50. static inline uint32_t max(uint32_t a, uint32_t b)
  51. {
  52. return a > b ? a : b;
  53. }
  54. enum futil_file_type ft_recognize_gbb(uint8_t *buf, uint32_t len)
  55. {
  56. GoogleBinaryBlockHeader *gbb = (GoogleBinaryBlockHeader *)buf;
  57. if (memcmp(gbb->signature, GBB_SIGNATURE, GBB_SIGNATURE_SIZE))
  58. return FILE_TYPE_UNKNOWN;
  59. if (gbb->major_version > GBB_MAJOR_VER)
  60. return FILE_TYPE_UNKNOWN;
  61. if (sizeof(GoogleBinaryBlockHeader) > len)
  62. return FILE_TYPE_UNKNOWN;
  63. /* close enough */
  64. return FILE_TYPE_GBB;
  65. }
  66. int futil_valid_gbb_header(GoogleBinaryBlockHeader *gbb, uint32_t len,
  67. uint32_t *maxlen_ptr)
  68. {
  69. if (len < sizeof(GoogleBinaryBlockHeader))
  70. return 0;
  71. if (memcmp(gbb->signature, GBB_SIGNATURE, GBB_SIGNATURE_SIZE))
  72. return 0;
  73. if (gbb->major_version != GBB_MAJOR_VER)
  74. return 0;
  75. /* Check limits first, to help identify problems */
  76. if (maxlen_ptr) {
  77. uint32_t maxlen = gbb->header_size;
  78. maxlen = max(maxlen,
  79. gbb->hwid_offset + gbb->hwid_size);
  80. maxlen = max(maxlen,
  81. gbb->rootkey_offset + gbb->rootkey_size);
  82. maxlen = max(maxlen,
  83. gbb->bmpfv_offset + gbb->bmpfv_size);
  84. maxlen = max(maxlen,
  85. gbb->recovery_key_offset + gbb->recovery_key_size);
  86. *maxlen_ptr = maxlen;
  87. }
  88. if (gbb->header_size != GBB_HEADER_SIZE || gbb->header_size > len)
  89. return 0;
  90. if (gbb->hwid_offset < GBB_HEADER_SIZE)
  91. return 0;
  92. if (gbb->hwid_offset + gbb->hwid_size > len)
  93. return 0;
  94. if (gbb->hwid_size) {
  95. const char *s = (const char *)
  96. ((uint8_t *)gbb + gbb->hwid_offset);
  97. if (!is_null_terminated(s, gbb->hwid_size))
  98. return 0;
  99. }
  100. if (gbb->rootkey_offset < GBB_HEADER_SIZE)
  101. return 0;
  102. if (gbb->rootkey_offset + gbb->rootkey_size > len)
  103. return 0;
  104. if (gbb->bmpfv_offset < GBB_HEADER_SIZE)
  105. return 0;
  106. if (gbb->bmpfv_offset + gbb->bmpfv_size > len)
  107. return 0;
  108. if (gbb->recovery_key_offset < GBB_HEADER_SIZE)
  109. return 0;
  110. if (gbb->recovery_key_offset + gbb->recovery_key_size > len)
  111. return 0;
  112. /* Seems legit... */
  113. return 1;
  114. }
  115. /* For GBB v1.2 and later, print the stored digest of the HWID (and whether
  116. * it's correct). Return true if it is correct. */
  117. int print_hwid_digest(GoogleBinaryBlockHeader *gbb,
  118. const char *banner, const char *footer)
  119. {
  120. printf("%s", banner);
  121. /* There isn't one for v1.1 and earlier, so assume it's good. */
  122. if (gbb->minor_version < 2) {
  123. printf("<none>%s", footer);
  124. return 1;
  125. }
  126. uint8_t *buf = (uint8_t *)gbb;
  127. char *hwid_str = (char *)(buf + gbb->hwid_offset);
  128. int is_valid = 0;
  129. uint8_t digest[VB2_SHA256_DIGEST_SIZE];
  130. if (VB2_SUCCESS == vb2_digest_buffer(buf + gbb->hwid_offset,
  131. strlen(hwid_str), VB2_HASH_SHA256,
  132. digest, sizeof(digest))) {
  133. int i;
  134. is_valid = 1;
  135. /* print it, comparing as we go */
  136. for (i = 0; i < VB2_SHA256_DIGEST_SIZE; i++) {
  137. printf("%02x", gbb->hwid_digest[i]);
  138. if (gbb->hwid_digest[i] != digest[i])
  139. is_valid = 0;
  140. }
  141. }
  142. printf(" %s", is_valid ? "valid" : "<invalid>");
  143. printf("%s", footer);
  144. return is_valid;
  145. }
  146. /* For GBB v1.2 and later, update the hwid_digest field. */
  147. void update_hwid_digest(GoogleBinaryBlockHeader *gbb)
  148. {
  149. /* There isn't one for v1.1 and earlier */
  150. if (gbb->minor_version < 2)
  151. return;
  152. uint8_t *buf = (uint8_t *)gbb;
  153. char *hwid_str = (char *)(buf + gbb->hwid_offset);
  154. vb2_digest_buffer(buf + gbb->hwid_offset, strlen(hwid_str),
  155. VB2_HASH_SHA256,
  156. gbb->hwid_digest, sizeof(gbb->hwid_digest));
  157. }
  158. /*
  159. * TODO: All sorts of race conditions likely here, and everywhere this is used.
  160. * Do we care? If so, fix it.
  161. */
  162. void futil_copy_file_or_die(const char *infile, const char *outfile)
  163. {
  164. pid_t pid;
  165. int status;
  166. Debug("%s(%s, %s)\n", __func__, infile, outfile);
  167. pid = fork();
  168. if (pid < 0) {
  169. fprintf(stderr, "Couldn't fork /bin/cp process: %s\n",
  170. strerror(errno));
  171. exit(1);
  172. }
  173. /* child */
  174. if (!pid) {
  175. execl("/bin/cp", "/bin/cp", infile, outfile, NULL);
  176. fprintf(stderr, "Child couldn't exec /bin/cp: %s\n",
  177. strerror(errno));
  178. exit(1);
  179. }
  180. /* parent - wait for child to finish */
  181. if (wait(&status) == -1) {
  182. fprintf(stderr,
  183. "Couldn't wait for /bin/cp process to exit: %s\n",
  184. strerror(errno));
  185. exit(1);
  186. }
  187. if (WIFEXITED(status)) {
  188. status = WEXITSTATUS(status);
  189. /* zero is normal exit */
  190. if (!status)
  191. return;
  192. fprintf(stderr, "/bin/cp exited with status %d\n", status);
  193. exit(1);
  194. }
  195. if (WIFSIGNALED(status)) {
  196. status = WTERMSIG(status);
  197. fprintf(stderr, "/bin/cp was killed with signal %d\n", status);
  198. exit(1);
  199. }
  200. fprintf(stderr, "I have no idea what just happened\n");
  201. exit(1);
  202. }
  203. enum futil_file_err futil_map_file(int fd, int writeable,
  204. uint8_t **buf, uint32_t *len)
  205. {
  206. struct stat sb;
  207. void *mmap_ptr;
  208. uint32_t reasonable_len;
  209. if (0 != fstat(fd, &sb)) {
  210. fprintf(stderr, "Can't stat input file: %s\n",
  211. strerror(errno));
  212. return FILE_ERR_STAT;
  213. }
  214. #ifndef HAVE_MACOS
  215. if (S_ISBLK(sb.st_mode))
  216. ioctl(fd, BLKGETSIZE64, &sb.st_size);
  217. #endif
  218. /* If the image is larger than 2^32 bytes, it's wrong. */
  219. if (sb.st_size < 0 || sb.st_size > UINT32_MAX) {
  220. fprintf(stderr, "Image size is unreasonable\n");
  221. return FILE_ERR_SIZE;
  222. }
  223. reasonable_len = (uint32_t)sb.st_size;
  224. if (writeable)
  225. mmap_ptr = mmap(0, sb.st_size,
  226. PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
  227. else
  228. mmap_ptr = mmap(0, sb.st_size,
  229. PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, 0);
  230. if (mmap_ptr == (void *)-1) {
  231. fprintf(stderr, "Can't mmap %s file: %s\n",
  232. writeable ? "output" : "input",
  233. strerror(errno));
  234. return FILE_ERR_MMAP;
  235. }
  236. *buf = (uint8_t *)mmap_ptr;
  237. *len = reasonable_len;
  238. return FILE_ERR_NONE;
  239. }
  240. enum futil_file_err futil_unmap_file(int fd, int writeable,
  241. uint8_t *buf, uint32_t len)
  242. {
  243. void *mmap_ptr = buf;
  244. enum futil_file_err err = FILE_ERR_NONE;
  245. if (writeable &&
  246. (0 != msync(mmap_ptr, len, MS_SYNC|MS_INVALIDATE))) {
  247. fprintf(stderr, "msync failed: %s\n", strerror(errno));
  248. err = FILE_ERR_MSYNC;
  249. }
  250. if (0 != munmap(mmap_ptr, len)) {
  251. fprintf(stderr, "Can't munmap pointer: %s\n",
  252. strerror(errno));
  253. if (err == FILE_ERR_NONE)
  254. err = FILE_ERR_MUNMAP;
  255. }
  256. return err;
  257. }
  258. #define DISK_SECTOR_SIZE 512
  259. enum futil_file_type ft_recognize_gpt(uint8_t *buf, uint32_t len)
  260. {
  261. GptHeader *h;
  262. /* GPT header starts at sector 1, is one sector long */
  263. if (len < 2 * DISK_SECTOR_SIZE)
  264. return FILE_TYPE_UNKNOWN;
  265. h = (GptHeader *)(buf + DISK_SECTOR_SIZE);
  266. if (memcmp(h->signature, GPT_HEADER_SIGNATURE,
  267. GPT_HEADER_SIGNATURE_SIZE) &&
  268. memcmp(h->signature, GPT_HEADER_SIGNATURE2,
  269. GPT_HEADER_SIGNATURE_SIZE))
  270. return FILE_TYPE_UNKNOWN;
  271. if (h->revision != GPT_HEADER_REVISION)
  272. return FILE_TYPE_UNKNOWN;
  273. if (h->size < MIN_SIZE_OF_HEADER || h->size > MAX_SIZE_OF_HEADER)
  274. return FILE_TYPE_UNKNOWN;
  275. if (HeaderCrc(h) != h->header_crc32)
  276. return FILE_TYPE_UNKNOWN;
  277. return FILE_TYPE_CHROMIUMOS_DISK;
  278. }