summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorKenneth R Westerback <krw@cvs.openbsd.org>2015-09-25 11:56:22 +0000
committerKenneth R Westerback <krw@cvs.openbsd.org>2015-09-25 11:56:22 +0000
commit378fffec3b5f6bd7ae2e03b55dd5c246f83f38f3 (patch)
tree1fd8c5e8e9b7e7f06c6735b3765cd6a2621ff48b /sys
parent0df99b969a1c93a9608031012e0d999dc2c29416 (diff)
Don't immediately try to checksum the GPT header using the size
field from the GPT header being checksum'd. First make sure the size is in a valid range. In particular ensure it won't cause crc32() to run off the end of the GPT header being checksum'd. Also check GPT signature and version first. These checks were inadvertantly moved after the checksumming. This should fix the system crash reported by Ze Loff on bugs@.
Diffstat (limited to 'sys')
-rw-r--r--sys/kern/subr_disk.c25
1 files changed, 10 insertions, 15 deletions
diff --git a/sys/kern/subr_disk.c b/sys/kern/subr_disk.c
index a169af5a279..2702b0ce248 100644
--- a/sys/kern/subr_disk.c
+++ b/sys/kern/subr_disk.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: subr_disk.c,v 1.219 2015/09/24 19:28:33 krw Exp $ */
+/* $OpenBSD: subr_disk.c,v 1.220 2015/09/25 11:56:21 krw Exp $ */
/* $NetBSD: subr_disk.c,v 1.17 1996/03/16 23:17:08 christos Exp $ */
/*
@@ -625,20 +625,12 @@ gpt_chk_hdr(struct gpt_header *gh, struct disklabel *lp)
{
uint64_t ghpartlba;
uint64_t ghlbaend, ghlbastart;
- uint32_t orig_gh_csum = gh->gh_csum;
+ uint32_t orig_gh_csum;
uint32_t ghsize, ghpartsize, ghpartspersec, ghpartnum;
- gh->gh_csum = 0;
- gh->gh_csum = crc32(0, (unsigned char *)gh,
- letoh32(gh->gh_size));
-
- if (orig_gh_csum != gh->gh_csum)
- return (EINVAL);
-
if (letoh64(gh->gh_sig) != GPTSIGNATURE)
return (EINVAL);
- /* we only support version 1.0 */
if (letoh32(gh->gh_rev) != GPTREVISION)
return (EINVAL);
@@ -650,11 +642,14 @@ gpt_chk_hdr(struct gpt_header *gh, struct disklabel *lp)
ghlbaend = letoh64(gh->gh_lba_end);
ghlbastart = letoh64(gh->gh_lba_start);
- /*
- * Header size must be greater than or equal to 92 and less
- * than or equal to the logical block size.
- */
- if (ghsize < GPTMINHDRSIZE || ghsize > lp->d_secsize)
+ if (ghsize < GPTMINHDRSIZE || ghsize > sizeof(struct gpt_header))
+ return (EINVAL);
+
+ orig_gh_csum = gh->gh_csum;
+ gh->gh_csum = 0;
+ gh->gh_csum = crc32(0, (unsigned char *)gh, ghsize);
+
+ if (orig_gh_csum != gh->gh_csum)
return (EINVAL);
if (ghlbastart >= DL_GETDSIZE(lp) ||