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&#15791;&#4038;&#33923;&#18290;&#31118;&#26941;&#18392;&#58493;&#1847;&#1101;&#32097;&#17203;&#60301;&#48406;&#22766;&#14142;&#61440;
   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&#15791;&#4038;&#33923;&#18290;&#31118;&#26941;&#18392;&#58493;&#1847;&#1101;&#32097;&#17203;&#60301;&#48406;&#22766;&#14142;&#61440;, 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