From 3fed8fd5e758c6f38637bc27240b81cee0599d72 Mon Sep 17 00:00:00 2001 From: guenther Date: Fri, 7 Jan 2022 02:26:53 +0000 Subject: [PATCH] Extract the slice from the zeroth swap device instead of assuming it's the 'b' slice and (sanity) check against the partition count. Also, make the "is union hibernate_info too large?" a compile time check. ok deraadt@ --- sys/kern/subr_hibernate.c | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/sys/kern/subr_hibernate.c b/sys/kern/subr_hibernate.c index a9831beb847..22a79a25708 100644 --- a/sys/kern/subr_hibernate.c +++ b/sys/kern/subr_hibernate.c @@ -1,4 +1,4 @@ -/* $OpenBSD: subr_hibernate.c,v 1.130 2022/01/04 18:13:31 guenther Exp $ */ +/* $OpenBSD: subr_hibernate.c,v 1.131 2022/01/07 02:26:53 guenther Exp $ */ /* * Copyright (c) 2011 Ariane van der Steldt @@ -35,6 +35,9 @@ #include +/* Make sure the signature can fit in one block */ +CTASSERT(sizeof(union hibernate_info) <= DEV_BSIZE); + /* * Hibernate piglet layout information * @@ -568,6 +571,7 @@ get_hibernate_info(union hibernate_info *hib, int suspend) { struct disklabel dl; char err_string[128], *dl_ret; + int part; #ifndef NO_PROPOLICE /* Save propolice guard */ @@ -591,19 +595,17 @@ get_hibernate_info(union hibernate_info *hib, int suspend) } /* Make sure we have a swap partition. */ - if (dl.d_partitions[1].p_fstype != FS_SWAP || - DL_GETPSIZE(&dl.d_partitions[1]) == 0) - return (1); - - /* Make sure the signature can fit in one block */ - if (sizeof(union hibernate_info) > DEV_BSIZE) + part = DISKPART(hib->dev); + if (dl.d_npartitions <= part || + dl.d_partitions[part].p_fstype != FS_SWAP || + DL_GETPSIZE(&dl.d_partitions[part]) == 0) return (1); /* Magic number */ hib->magic = HIBERNATE_MAGIC; /* Calculate signature block location */ - hib->sig_offset = DL_GETPSIZE(&dl.d_partitions[1]) - + hib->sig_offset = DL_GETPSIZE(&dl.d_partitions[part]) - sizeof(union hibernate_info)/DEV_BSIZE; /* Stash kernel version information */ @@ -626,8 +628,8 @@ get_hibernate_info(union hibernate_info *hib, int suspend) * a matching HIB_DONE call performed after the write is * completed. */ - if (hib->io_func(hib->dev, DL_GETPOFFSET(&dl.d_partitions[1]), - (vaddr_t)NULL, DL_GETPSIZE(&dl.d_partitions[1]), + if (hib->io_func(hib->dev, DL_GETPOFFSET(&dl.d_partitions[part]), + (vaddr_t)NULL, DL_GETPSIZE(&dl.d_partitions[part]), HIB_INIT, hib->io_page)) goto fail; -- 2.20.1