partitions/efi: Fix partition name parsing in GUID partition entry
GUID partition entry defined to have a partition name as 36 UTF-16LE
code units. This means that on big-endian platforms ASCII symbols
would be read with 0xXX00 efi_char16_t character code. In order to
correctly extract ASCII characters from a partition name field we
should be converted from 16LE to CPU architecture.
The problem exists on all big endian platforms.
[ mingo: Minor edits. ]
Fixes: eec7ecfede
("genhd, efi: add efi partition metadata to hd_structs")
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Nikolai Merinov <n.merinov@inango-systems.com>
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Link: https://lore.kernel.org/r/20200308080859.21568-29-ardb@kernel.org
Link: https://lore.kernel.org/r/797777312.1324734.1582544319435.JavaMail.zimbra@inango-systems.com/
This commit is contained in:
parent
0347d8c28c
commit
d5528d5e91
|
@ -656,6 +656,31 @@ static int find_valid_gpt(struct parsed_partitions *state, gpt_header **gpt,
|
|||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* utf16_le_to_7bit(): Naively converts a UTF-16LE string to 7-bit ASCII characters
|
||||
* @in: input UTF-16LE string
|
||||
* @size: size of the input string
|
||||
* @out: output string ptr, should be capable to store @size+1 characters
|
||||
*
|
||||
* Description: Converts @size UTF16-LE symbols from @in string to 7-bit
|
||||
* ASCII characters and stores them to @out. Adds trailing zero to @out array.
|
||||
*/
|
||||
static void utf16_le_to_7bit(const __le16 *in, unsigned int size, u8 *out)
|
||||
{
|
||||
unsigned int i = 0;
|
||||
|
||||
out[size] = 0;
|
||||
|
||||
while (i < size) {
|
||||
u8 c = le16_to_cpu(in[i]) & 0xff;
|
||||
|
||||
if (c && !isprint(c))
|
||||
c = '!';
|
||||
out[i] = c;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* efi_partition(struct parsed_partitions *state)
|
||||
* @state: disk parsed partitions
|
||||
|
@ -692,7 +717,6 @@ int efi_partition(struct parsed_partitions *state)
|
|||
|
||||
for (i = 0; i < le32_to_cpu(gpt->num_partition_entries) && i < state->limit-1; i++) {
|
||||
struct partition_meta_info *info;
|
||||
unsigned label_count = 0;
|
||||
unsigned label_max;
|
||||
u64 start = le64_to_cpu(ptes[i].starting_lba);
|
||||
u64 size = le64_to_cpu(ptes[i].ending_lba) -
|
||||
|
@ -713,14 +737,7 @@ int efi_partition(struct parsed_partitions *state)
|
|||
/* Naively convert UTF16-LE to 7 bits. */
|
||||
label_max = min(ARRAY_SIZE(info->volname) - 1,
|
||||
ARRAY_SIZE(ptes[i].partition_name));
|
||||
info->volname[label_max] = 0;
|
||||
while (label_count < label_max) {
|
||||
u8 c = ptes[i].partition_name[label_count] & 0xff;
|
||||
if (c && !isprint(c))
|
||||
c = '!';
|
||||
info->volname[label_count] = c;
|
||||
label_count++;
|
||||
}
|
||||
utf16_le_to_7bit(ptes[i].partition_name, label_max, info->volname);
|
||||
state->parts[i + 1].has_info = true;
|
||||
}
|
||||
kfree(ptes);
|
||||
|
|
|
@ -88,7 +88,7 @@ typedef struct _gpt_entry {
|
|||
__le64 starting_lba;
|
||||
__le64 ending_lba;
|
||||
gpt_entry_attributes attributes;
|
||||
efi_char16_t partition_name[72 / sizeof (efi_char16_t)];
|
||||
__le16 partition_name[72/sizeof(__le16)];
|
||||
} __packed gpt_entry;
|
||||
|
||||
typedef struct _gpt_mbr_record {
|
||||
|
|
Loading…
Reference in New Issue