Saturday, December 25, 2021

Re: Disk partition not recognized

--- subr_disk.c.dist Tue Jan 19 16:36:48 2021
+++ subr_disk.c Sat Dec 25 10:30:01 2021
@@ -606,7 +606,7 @@
if (dp2->dp_typ != DOSPTYP_EFI)
continue;
psize = letoh32(dp2->dp_size);
- if (psize == (dsize - 1) ||
+ if (psize <= (dsize - 1) ||
psize == UINT32_MAX) {
if (letoh32(dp2->dp_start) == 1)
efi++;
@@ -805,7 +805,7 @@
bcopy(bp->b_data, gp + i * ghpartspersec,
ghpartspersec * sizeof(struct gpt_partition));
}
-
+/*
if (gpt_chk_parts(&gh, gp)) {
free(gp, M_DEVBUF, gpsz);
if (altheader) {
@@ -815,6 +815,7 @@
}
continue;
}
+*/
break;
}

--- subr_disk.c.dist Thu Dec 23 19:53:52 2021
+++ subr_disk.c Sat Dec 25 10:31:09 2021
@@ -802,7 +802,7 @@
bcopy(bp->b_data, gp + i * ghpartspersec,
ghpartspersec * sizeof(struct gpt_partition));
}
-
+/*
if (gpt_chk_parts(&gh, gp)) {
free(gp, M_DEVBUF, gpsz);
if (letoh64(gh.gh_lba_self) != GPTSECTOR) {
@@ -812,6 +812,7 @@
}
continue;
}
+*/
break;
}

On Thu, Dec 23, 2021 at 08:11:31PM -0300, Crystal Kolipe wrote:
> On Thu, Dec 23, 2021 at 07:28:19PM -0300, Crystal Kolipe wrote:
> > On Thu, Dec 23, 2021 at 04:15:50PM -0500, Rob Whitlock wrote:
> > > On Thu, Dec 23, 2021 at 3:24 PM Crystal Kolipe <kolipe.c@exoticsilicon.com>
> > > wrote:
> > >
> > > > Again, there is nothing there that would stop it working.
> > > >
> > > > You have an MBR partition of type EE starting on sector 1, which is what is
> > > > checked for in gpt_chk_mbr, so unless I'm overlooking something it's
> > > > probably chocking in gpt_chk_hdr due to something unexpected in the GPT
> > > > header,
> > > > (LBA block 1).
> > > >
> > >
> > > Here is LBA block 1:
> >
> > OK, I now know why it's not working :-).
> >
> > Either:
> >
> > * Upgrade to OpenBSD 7.0
> >
> > or
> >
> > * Change line 610 of /usr/src/kern/subr_disk.c as it changed between
> > version 1.241 and version 1.242:
> >
> > https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/sys/kern/subr_disk.c.diff?r1=1.241&r2=1.242&f=h
> >
> > ... and recompile the kernel.
> >
> > Either way, the spoofed disklabel will then include your non-OpenBSD partitions.
> >
> > And in future, please test the latest version of the code before reporting a bug ;-).
>
> Hang on, that's only part of the problem, there is something else wrong too...
>
> I was testing with a slightly different GPT header, (block 1), when I observed
> the issue I described above. The fix I gave does indeed work for the GPT
> header that I was using for testing.
>
> However, I just tested it with your exact GPT header block, and it still fails
> to see the non-OpenBSD partitions.
>
> But looking at the two, the only fields that are different are the four bytes
> at offset 0x10, which are a CRC, the 16 bytes at offset 0x38, which are the
> disk GUID, and the four bytes at offset 0x58, which are another CRC.
>
> I won't have time to look in to this further for the next couple of days,
> which is why I'm posting this in case somebody else wants to step up and
> resolve it.
>
> --- works.hex Thu Dec 23 20:02:08 2021
> +++ doesnt.hex Thu Dec 23 20:02:02 2021
> @@ -6,11 +6,11 @@
> *
> 000001f0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 55 aa |..............U.|
> 00000200 45 46 49 20 50 41 52 54 00 00 01 00 5c 00 00 00 |EFI PART....\...|
> -00000210 c2 7d c2 16 00 00 00 00 01 00 00 00 00 00 00 00 |.}..............|
> +00000210 34 b3 c1 18 00 00 00 00 01 00 00 00 00 00 00 00 |4...............|
> 00000220 ae d9 30 46 02 00 00 00 22 00 00 00 00 00 00 00 |..0F....".......|
> -00000230 8d d9 30 46 02 00 00 00 07 8f ed 99 ec 89 df 45 |..0F...........E|
> -00000240 a5 38 96 c6 05 d7 c5 e9 02 00 00 00 00 00 00 00 |.8..............|
> -00000250 80 00 00 00 80 00 00 00 52 9e e8 0b 00 00 00 00 |........R.......|
> +00000230 8d d9 30 46 02 00 00 00 69 b0 0a 57 69 18 ed 44 |..0F....i..Wi..D|
> +00000240 91 1b a5 68 af 12 75 ff 02 00 00 00 00 00 00 00 |...h..u.........|
> +00000250 80 00 00 00 80 00 00 00 6c 88 7a 3f 00 00 00 00 |........l.z?....|
> 00000260 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
> *
> 00000400 28 73 2a c1 1f f8 d2 11 ba 4b 00 a0 c9 3e c9 3b |(s*......K...>.;|

OK, the issue lies with the four byte checksum at offset 0x58 in sector 1.

Testing on OpenBSD 7.0 release and using your GPT:

The kernel enters spoofgptlabel and reads sector 1.

When we call gpt_chk_parts, the calculated checksum comes to 0x0BE89E52, whereas the on-disk checksum is 0x3F7A886C, as you can see in the hexdumps.

Note that the on-disk checksum is stored in little-endian format.

As a result, gpt_chk_parts returns EINVAL. When control returns to spoofgptlabel, it doesn't read the partitions contained within, and goes on to try to read the second GPT at sector dsize-1, which in your case is sector 9767541167.

That's the reason why you don't see the non-OpenBSD partitions in your, (spoofed), disklabel, the on-disk checksum of the partition entries does not match the calculated checksum, so the kernel considers the GPT to be invalid.

If you want to test removing the call to gpt_chk_parts, thereby forcing the kernel to parse whatever it finds and ignoring any checksum errors, the attached diffs should allow you to do that. As you said that you were still running OpenBSD 6.9, I've produced a diff against that too, including the change in line 609 that I mentioned earlier, but it's untested. There were other changes to this code between 6.9 and 7.0 that I have not really looked at.

On OpenBSD 7.0, with the diff applied, I am able to parse the GPT that you supplied.

I doubt that a kernel option to disable the checksum verification would be appropriate or welcome, but I don't know how common the problem is.

No comments:

Post a Comment