[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PULL 3/7] vvfat: create_long_filename: fix out-of-bounds array access
From: |
Michael Tokarev |
Subject: |
[PULL 3/7] vvfat: create_long_filename: fix out-of-bounds array access |
Date: |
Thu, 30 Jan 2025 16:34:43 +0300 |
create_long_filename() intentionally uses direntry_t->name[8+3] array
as a larger array. This works, but makes static code analysis tools
unhappy. The problem here is that a directory entry holding long file
name is significantly different from regular directory entry, and the
name is split into several parts within the entry, not just in regular
8+3 name field.
Treat the entry as array of bytes instead. This fixes the OOB access
from the compiler/tools PoV, but does not change the resulting code
in any way.
Keep the existing code style.
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
---
block/vvfat.c | 11 +++++------
1 file changed, 5 insertions(+), 6 deletions(-)
diff --git a/block/vvfat.c b/block/vvfat.c
index 8ffe8b3b9b..bfbcc5562c 100644
--- a/block/vvfat.c
+++ b/block/vvfat.c
@@ -403,7 +403,6 @@ static direntry_t *create_long_filename(BDRVVVFATState *s,
const char *filename)
{
int number_of_entries, i;
glong length;
- direntry_t *entry;
gunichar2 *longname = g_utf8_to_utf16(filename, -1, NULL, &length, NULL);
if (!longname) {
@@ -414,24 +413,24 @@ static direntry_t *create_long_filename(BDRVVVFATState
*s, const char *filename)
number_of_entries = DIV_ROUND_UP(length * 2, 26);
for(i=0;i<number_of_entries;i++) {
- entry=array_get_next(&(s->directory));
+ direntry_t *entry=array_get_next(&(s->directory));
entry->attributes=0xf;
entry->reserved[0]=0;
entry->begin=0;
entry->name[0]=(number_of_entries-i)|(i==0?0x40:0);
}
for(i=0;i<26*number_of_entries;i++) {
+ unsigned char
*entry=array_get(&(s->directory),s->directory.next-1-(i/26));
int offset=(i%26);
if(offset<10) offset=1+offset;
else if(offset<22) offset=14+offset-10;
else offset=28+offset-22;
- entry=array_get(&(s->directory),s->directory.next-1-(i/26));
if (i >= 2 * length + 2) {
- entry->name[offset] = 0xff;
+ entry[offset] = 0xff;
} else if (i % 2 == 0) {
- entry->name[offset] = longname[i / 2] & 0xff;
+ entry[offset] = longname[i / 2] & 0xff;
} else {
- entry->name[offset] = longname[i / 2] >> 8;
+ entry[offset] = longname[i / 2] >> 8;
}
}
g_free(longname);
--
2.39.5
- [PULL 0/7] Trivial patches for 2025-01-30, Michael Tokarev, 2025/01/30
- [PULL 1/7] net: Fix announce_self, Michael Tokarev, 2025/01/30
- [PULL 2/7] net/dump: Correctly compute Ethernet packet offset, Michael Tokarev, 2025/01/30
- [PULL 3/7] vvfat: create_long_filename: fix out-of-bounds array access,
Michael Tokarev <=
- [PULL 4/7] gdbstub/user-target: fix gdbserver int format (%d -> %x), Michael Tokarev, 2025/01/30
- [PULL 5/7] tests/functional/test_mips_malta: Fix comment about endianness of the test, Michael Tokarev, 2025/01/30
- [PULL 6/7] licenses: Remove SPDX tags not being license identifier for Linaro, Michael Tokarev, 2025/01/30
- [PULL 7/7] hw/i386/pc: Remove unused pc_compat_2_3 declarations, Michael Tokarev, 2025/01/30