diff options
author | Jaegeuk Kim <jaegeuk@kernel.org> | 2023-05-05 09:18:30 -0700 |
---|---|---|
committer | Jaegeuk Kim <jaegeuk@kernel.org> | 2023-05-17 18:12:57 -0700 |
commit | f89e5af24efeb1519ffc9e3b0dc9d9c231e35d05 (patch) | |
tree | 8bbab83176fd527ba4dcb5b26732feb32384685d | |
parent | 23ef5f5d831a16132dc1ad86eb73dc6281c92708 (diff) | |
download | f2fs-tools-f89e5af24efeb1519ffc9e3b0dc9d9c231e35d05.tar.gz |
f2fs-tools: allocate memory to handle label
Let's avoid memory alignment of sb->volume_name.
Reviewed-by: Chao Yu <chao@kernel.org>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
-rw-r--r-- | fsck/main.c | 4 | ||||
-rw-r--r-- | fsck/mount.c | 4 | ||||
-rw-r--r-- | include/f2fs_fs.h | 4 | ||||
-rw-r--r-- | lib/libf2fs.c | 37 | ||||
-rw-r--r-- | mkfs/f2fs_format.c | 2 |
5 files changed, 35 insertions, 16 deletions
diff --git a/fsck/main.c b/fsck/main.c index 9b50787..b01b52c 100644 --- a/fsck/main.c +++ b/fsck/main.c @@ -1051,7 +1051,7 @@ static int do_label(struct f2fs_sb_info *sbi) if (!c.vol_label) { char label[MAX_VOLUME_NAME]; - utf16_to_utf8(label, sb->volume_name, + utf16_to_utf8(label, (const char *)sb->volume_name, MAX_VOLUME_NAME, MAX_VOLUME_NAME); MSG(0, "Info: volume label = %s\n", label); return 0; @@ -1062,7 +1062,7 @@ static int do_label(struct f2fs_sb_info *sbi) return -1; } - utf8_to_utf16(sb->volume_name, (const char *)c.vol_label, + utf8_to_utf16((char *)sb->volume_name, (const char *)c.vol_label, MAX_VOLUME_NAME, strlen(c.vol_label)); update_superblock(sb, SB_MASK_ALL); diff --git a/fsck/mount.c b/fsck/mount.c index df0314d..9209558 100644 --- a/fsck/mount.c +++ b/fsck/mount.c @@ -365,7 +365,7 @@ void print_node_info(struct f2fs_sb_info *sbi, } } -static void DISP_label(uint16_t *name) +static void DISP_label(const char *name) { char buffer[MAX_VOLUME_NAME]; @@ -391,7 +391,7 @@ printout: DISP_u32(sb, magic); DISP_u32(sb, major_ver); - DISP_label(sb->volume_name); + DISP_label((const char *)sb->volume_name); DISP_u32(sb, minor_ver); DISP_u32(sb, log_sectorsize); diff --git a/include/f2fs_fs.h b/include/f2fs_fs.h index 6948814..832dee2 100644 --- a/include/f2fs_fs.h +++ b/include/f2fs_fs.h @@ -1430,8 +1430,8 @@ enum { SSR }; -extern int utf8_to_utf16(uint16_t *, const char *, size_t, size_t); -extern int utf16_to_utf8(char *, const uint16_t *, size_t, size_t); +extern int utf8_to_utf16(char *, const char *, size_t, size_t); +extern int utf16_to_utf8(char *, const char *, size_t, size_t); extern int log_base_2(uint32_t); extern unsigned int addrs_per_inode(struct f2fs_inode *); extern unsigned int addrs_per_block(struct f2fs_inode *); diff --git a/lib/libf2fs.c b/lib/libf2fs.c index 6b879f9..aa7f15b 100644 --- a/lib/libf2fs.c +++ b/lib/libf2fs.c @@ -115,31 +115,40 @@ static uint16_t *wchar_to_utf16(uint16_t *output, wchar_t wc, size_t outsize) return output + 2; } -int utf8_to_utf16(uint16_t *output, const char *input, size_t outsize, +int utf8_to_utf16(char *output, const char *input, size_t outsize, size_t insize) { const char *inp = input; - uint16_t *outp = output; + uint16_t *outp; wchar_t wc; + uint16_t *volume_name = calloc(sizeof(uint16_t), MAX_VOLUME_NAME); + + if (!volume_name) + return -ENOMEM; + + outp = volume_name; while ((size_t)(inp - input) < insize && *inp) { inp = utf8_to_wchar(inp, &wc, insize - (inp - input)); if (inp == NULL) { DBG(0, "illegal UTF-8 sequence\n"); + free(volume_name); return -EILSEQ; } - outp = wchar_to_utf16(outp, wc, outsize - (outp - output)); + outp = wchar_to_utf16(outp, wc, outsize - (outp - volume_name)); if (outp == NULL) { DBG(0, "name is too long\n"); + free(volume_name); return -ENAMETOOLONG; } } *outp = cpu_to_le16(0); + memcpy(output, volume_name, sizeof(uint16_t) * MAX_VOLUME_NAME); + free(volume_name); return 0; } -static const uint16_t *utf16_to_wchar(const uint16_t *input, wchar_t *wc, - size_t insize) +static uint16_t *utf16_to_wchar(uint16_t *input, wchar_t *wc, size_t insize) { if ((le16_to_cpu(input[0]) & 0xfc00) == 0xd800) { if (insize < 2 || (le16_to_cpu(input[1]) & 0xfc00) != 0xdc00) @@ -201,26 +210,36 @@ static char *wchar_to_utf8(char *output, wchar_t wc, size_t outsize) return output; } -int utf16_to_utf8(char *output, const uint16_t *input, size_t outsize, +int utf16_to_utf8(char *output, const char *input, size_t outsize, size_t insize) { - const uint16_t *inp = input; char *outp = output; wchar_t wc; + uint16_t *inp; + uint16_t *volume_name = calloc(sizeof(uint16_t), MAX_VOLUME_NAME); + + if (!volume_name) + return -ENOMEM; + + memcpy(volume_name, input, sizeof(uint16_t) * MAX_VOLUME_NAME); + inp = volume_name; - while ((size_t)(inp - input) < insize && le16_to_cpu(*inp)) { - inp = utf16_to_wchar(inp, &wc, insize - (inp - input)); + while ((size_t)(inp - volume_name) < insize && le16_to_cpu(*inp)) { + inp = utf16_to_wchar(inp, &wc, insize - (inp - volume_name)); if (inp == NULL) { DBG(0, "illegal UTF-16 sequence\n"); + free(volume_name); return -EILSEQ; } outp = wchar_to_utf8(outp, wc, outsize - (outp - output)); if (outp == NULL) { DBG(0, "name is too long\n"); + free(volume_name); return -ENAMETOOLONG; } } *outp = '\0'; + free(volume_name); return 0; } diff --git a/mkfs/f2fs_format.c b/mkfs/f2fs_format.c index d3bb622..3e49057 100644 --- a/mkfs/f2fs_format.c +++ b/mkfs/f2fs_format.c @@ -512,7 +512,7 @@ static int f2fs_prepare_super_block(void) if (c.feature & cpu_to_le32(F2FS_FEATURE_INODE_CHKSUM)) c.chksum_seed = f2fs_cal_crc32(~0, sb->uuid, sizeof(sb->uuid)); - utf8_to_utf16(sb->volume_name, (const char *)c.vol_label, + utf8_to_utf16((char *)sb->volume_name, (const char *)c.vol_label, MAX_VOLUME_NAME, strlen(c.vol_label)); set_sb(node_ino, 1); set_sb(meta_ino, 2); |