gpt_write: address unaligned access for name

Turn member into byte array to prevent unaligned memory access.

Fixes #4141.
This commit is contained in:
Josef Söntgen 2021-05-06 13:24:58 +02:00 committed by Christian Helmuth
parent d19b751632
commit c5c3d7ca98
3 changed files with 29 additions and 22 deletions

View File

@ -111,13 +111,13 @@ namespace Gpt {
*/ */
struct Entry struct Entry
{ {
enum { NAME_LEN = 36 }; enum { NAME_BYTES = 36 * 2 };
Uuid type; /* partition type GUID */ Uuid type; /* partition type GUID */
Uuid guid; /* unique partition GUID */ Uuid guid; /* unique partition GUID */
uint64_t lba_start; /* start of partition */ uint64_t lba_start; /* start of partition */
uint64_t lba_end; /* end of partition */ uint64_t lba_end; /* end of partition */
uint64_t attributes; /* partition attributes */ uint64_t attributes; /* partition attributes */
uint16_t name[NAME_LEN]; /* partition name in UTF-16LE */ uint8_t name[NAME_BYTES]; /* partition name in UTF-16LE */
bool valid() const { return type.valid(); } bool valid() const { return type.valid(); }
@ -126,7 +126,7 @@ namespace Gpt {
*/ */
bool read_name(char *dest, size_t dest_len) const bool read_name(char *dest, size_t dest_len) const
{ {
return !!Util::extract_ascii(dest, dest_len, name, NAME_LEN); return !!Util::extract_ascii(dest, dest_len, name, NAME_BYTES);
} }
/** /**
@ -134,7 +134,7 @@ namespace Gpt {
*/ */
bool write_name(Label const &label) bool write_name(Label const &label)
{ {
return !!Util::convert_ascii(name, NAME_LEN, return !!Util::convert_ascii(name, NAME_BYTES,
(uint8_t*)label.string(), (uint8_t*)label.string(),
label.length() - 1); label.length() - 1);
} }

View File

@ -166,21 +166,27 @@ Genode::uint32_t Util::crc32(void const * const buf, Genode::size_t size)
* \return length of resulting ASCII string * \return length of resulting ASCII string
*/ */
Genode::size_t Util::extract_ascii(char *dest, size_t dest_len, Genode::size_t Util::extract_ascii(char *dest, size_t dest_len,
uint16_t const *src, size_t src_len) uint8_t const *src, size_t src_len)
{ {
char *p = dest; char *p = dest;
size_t j = 0; size_t j = 0;
size_t i = 0; size_t i = 0;
for (size_t u = 0; u < src_len && src[u] != 0; u++) { for (size_t u = 0; u < src_len; u += 2) {
uint32_t utfchar = src[i++]; uint16_t const nul = src[u] | (src[u+1] << 8);
if (!nul) { break; }
uint16_t const v = src[i] | (src[i+1] << 8);
i+=2;
uint32_t utfchar = v;
if ((utfchar & 0xf800) == 0xd800) { if ((utfchar & 0xf800) == 0xd800) {
unsigned int c = src[i]; uint32_t c = src[i] | (src[i+1] << 8);
if ((utfchar & 0x400) != 0 || (c & 0xfc00) != 0xdc00) { if ((utfchar & 0x400) != 0 || (c & 0xfc00) != 0xdc00) {
utfchar = 0xfffd; utfchar = 0xfffd;
} else { } else {
i++; i+=2;
} }
} }
@ -201,26 +207,27 @@ Genode::size_t Util::extract_ascii(char *dest, size_t dest_len,
* truncate the input string if it does not fit. * truncate the input string if it does not fit.
* *
* \param dest pointer to destination buffer * \param dest pointer to destination buffer
* \param dest_len length of the destination buffer in 16bit words * \param dest_len length of the destination buffer in bytes
* \param src pointer to source buffer * \param src pointer to source buffer
* \param dest_len length of the source buffer in 8bit words * \param dest_len length of the source buffer in 8bit words
* *
* \return length of resulting UTF-16 string * \return length of resulting UTF-16 string
*/ */
Genode::size_t Util::convert_ascii(uint16_t *dest, size_t dest_len, Genode::size_t Util::convert_ascii(uint8_t *dest, size_t dest_len,
uint8_t const *src, size_t src_len) uint8_t const *src, size_t src_len)
{ {
Genode::memset(dest, 0, dest_len * sizeof(uint16_t)); Genode::memset(dest, 0, dest_len);
if (src_len / sizeof(uint16_t) > dest_len) { if (src_len > dest_len) {
Genode::warning("input too long, will be truncated"); Genode::warning("input too long, will be truncated");
src_len = dest_len; src_len = dest_len;
} }
size_t i = 0; size_t i = 0;
size_t j = 0;
for (; i < src_len; i++) { for (; i < src_len; i++) {
uint16_t const utfchar = src[i]; dest[j++] = src[i];
dest[i] = utfchar; dest[j++] = 0;
} }
return i; return i;

View File

@ -41,8 +41,8 @@ namespace Util {
struct Block_io; struct Block_io;
uint32_t crc32(void const * const, size_t); uint32_t crc32(void const * const, size_t);
size_t extract_ascii(char *, size_t, uint16_t const *, size_t); size_t extract_ascii(char *, size_t, uint8_t const *, size_t);
size_t convert_ascii(uint16_t *, size_t, uint8_t const *, size_t); size_t convert_ascii(uint8_t *, size_t, uint8_t const *, size_t);
/* /*
* Wrapper to get suffixed uint64_t values * Wrapper to get suffixed uint64_t values