NetBSD-Bugs archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
kern/52522: incorrect partition label handling in gpt(8) and kernel (wedges)
>Number: 52522
>Category: kern
>Synopsis: incorrect partition label handling in gpt(8) and kernel (wedges)
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: kern-bug-people
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Sun Sep 03 13:20:00 +0000 2017
>Originator: Piotr Meyer
>Release: 8.0_BETA
>Organization:
>Environment:
NetBSD localhost 8.0_BETA NetBSD 8.0_BETA (GENERIC.201708300150Z) amd64
>Description:
gpt(8) and kernel incorrectly treats GPT partition labels as NULL-terminated strings[2] (in fact label is a "36 UTF-16LE code units", typically padded by zeros if they are shorter than 36 units, but NOT zero-terminated!)[1].
This behaviour leads to:
- inconsistencies between auto-generated wedge names and user-submitted ones
- truncating valid names (thus - there is impossible to use valid UUID as partition and wedge name when gpt(*) is used)
- incorrect naming of wedges from GPT partitions created on other systems (kernel expects null-terminated strings and do not check limits)
1 - see https://en.wikipedia.org/wiki/GUID_Partition_Table or compare with behaviour in other systems.
2 - https://nxr.netbsd.org/xref/src/sbin/gpt/gpt.c#227
>How-To-Repeat:
Create some partition by GPT:
# partition without label, wedge name created by kernel - valid UUID
localhost# gpt add -b 34 -s 33264 -t ffs wd1
/dev/rwd1: Partition 1 added: 49f48d5a-b10e-11dc-b99b-0019d1879648 34 33264
dmesg: dk0 at wd1: "58589a53-8481-4f5d-b415-c92e0aed99f4", 33264 blocks at 34, type: ffs
# short name, terminated by gpt(8) with zero, valid name and valid wedge name
localhost# gpt add -l testshort -b $((34+33264)) -s 33264 -t ffs wd1
/dev/rwd1: Partition 2 added: 49f48d5a-b10e-11dc-b99b-0019d1879648 33298 33264
dmesg: dk1 at wd1: "testshort", 33264 blocks at 33298, type: ffs
# [some wedges skipped]
# partition name with valid label - 36 bytes - as you can see label is truncated, as well as wedge name
localhost# gpt add -l 123456789012345678901234567890123456 -b $((99826+33264)) -s 33264 -t ffs wd1
/dev/rwd1: Partition 5 added: 49f48d5a-b10e-11dc-b99b-0019d1879648 133090 33264
dmesg: dk4 at wd1: "12345678901234567890123456789012345", 33264 blocks at 133090, type: ffs
# partition named by UUID create by uuidgen
localhost# uuidgen
b7462824-5cd3-42f8-9d7c-e0b2cd6da6da
# UUID is trunctated
localhost# gpt add -l b7462824-5cd3-42f8-9d7c-e0b2cd6da6da -b $((133090+33264)) -s 33264 -t ffs wd1
/dev/rwd1: Partition 6 added: 49f48d5a-b10e-11dc-b99b-0019d1879648 166354 33264
dmesg: dk5 at wd1: "b7462824-5cd3-42f8-9d7c-e0b2cd6da6d", 33264 blocks at 166354, type: ffs
#
#
# !!! example for wedge create automatically from partition created by parted on linux
#
#
[snip]
dk5 at wd1: "b7462824-5cd3-42f8-9d7c-e0b2cd6da6d", 33264 blocks at 166354, type: ffs
dk6 at wd1: "123456789012345678901234567890123456M-cM-6M-/M-`M-?M^FM-hM^RM^CM-dM^]M-2M-gM-&M^NM-fM-$M-=M-dM^_M^XM-nM^QM-=M-\M-7M-QM^MM-gM-5M-!M-dM^LM-3M-nM-.M^MM-kM-4M^VM-eM-#M-.M-cM^\M->M-oM^@M^@^C", 58195 blocks at 199618, type: <unknown>
dk7 at wd1: "123456789012345678901234567890123456", 30720 blocks at 258048, type: <unknown>
[snip]
# partition table
localhost# gpt show -l wd1
start size index contents
0 1 PMBR
1 1 Pri GPT header
2 32 Pri GPT table
34 33264 1 GPT part -
33298 33264 2 GPT part - testshort
66562 33264 3 GPT part - ccccccccccccccccccccccccccccccccccc
99826 33264 4 GPT part - ccccccccccccccccccccccccccccccccccc
133090 33264 5 GPT part - 12345678901234567890123456789012345
166354 33264 6 GPT part - b7462824-5cd3-42f8-9d7c-e0b2cd6da6d
199618 58195 7 GPT part - 123456789012345678901234567890123456㶯࿆蒃䝲禎椽䟘ܷэ絡䌳봖壮㜾
257813 235 Unused
258048 30720 8 GPT part - 123456789012345678901234567890123456
288768 3905503 Unused
4194271 32 Sec GPT table
4194303 1 Sec GPT header
localhost#
#
# wedges - look at inconsistency in autogenerated wedge names and truncated by gpt(8) ones
# - dk0 and dk3 vs dk4 or dk5
#
localhost# dkctl wd1 show
dkctl: unknown command: show
localhost# dkctl wd1 listwedges
/dev/rwd1: 8 wedges:
dk0: 58589a53-8481-4f5d-b415-c92e0aed99f4, 33264 blocks at 34, type: ffs
dk1: testshort, 33264 blocks at 33298, type: ffs
dk2: ccccccccccccccccccccccccccccccccccc, 33264 blocks at 66562, type: ffs
dk3: 0dcfa3a0-890e-42e4-866d-2d8b49f2ed24, 33264 blocks at 99826, type: ffs
dk4: 12345678901234567890123456789012345, 33264 blocks at 133090, type: ffs
dk5: b7462824-5cd3-42f8-9d7c-e0b2cd6da6d, 33264 blocks at 166354, type: ffs
dk6: 123456789012345678901234567890123456㶯࿆蒃䝲禎椽䟘ܷэ絡䌳봖壮㜾, 58195 blocks at 199618, type:
dk7: 123456789012345678901234567890123456, 30720 blocks at 258048, type:
>Fix:
1. Change gpt(8) behavior:
- do not assume that label is NULL-terminated - instead check for NULL or buffer end (72 bytes/376 UTF-16 chars)
- maybe pre-fill dst utf-18 buffer by NULLS to gracefully handle short names but do not replace last UTF-16 by NULL as they do now
2. Change kernel behaviour - do not assume that GPT label is null-terminated, see https://nxr.netbsd.org/xref/src/sys/dev/dkwedge/dkwedge_gpt.c#107
Home |
Main Index |
Thread Index |
Old Index