Arash - commented: 
https://gitlab.rtems.org/rtems/rtos/rtems/-/work_items/5656#note_155148


There's a heap out-of-bounds write in the RTEMS FAT filesystem (dosfs) 
long-file- name (LFN) directory reader, reachable from a mounted malicious FAT 
image on the first readdir(), in the default configuration.

Component: cpukit/libfs/src/dosfs -- msdos_dir_read() LFN reassembly 
(msdos_dir.c) + msdos_get_utf16_string_from_long_entry() (msdos_misc.c); 
default UTF-16

[poc-rtems-fs.zip](/uploads/5f70561288677d7986082da031f61492/poc-rtems-fs.zip)

misc.c); default UTF-16 converter (msdos_conv_default.c, 520-byte buffer). 
Version: current HEAD (4840472) and all versions with the converter-based LFN 
reader. Type: CWE-787 out-of-bounds write via CWE-131 (byte size vs uint16 
index) / CWE-1284. Severity: CVSS 3.1 \~7.8 High (est.) 
AV:L/AC:L/PR:N/UI:N/S:U/C:L/I:H/A:H.

## Root cause

lfn_buf is a uint16_t\* view of a 520-BYTE converter buffer 
(msdos_dir.c:78,80). For an LFN entry, msdos_dir.c reads the sequence ordinal 
straight from disk with no clamp to the 20- entry maximum:

:184 lfn_entries = entry\[0\] & MSDOS_LAST_LONG_ENTRY_MASK; /\* 0..63 _/ :219 
lfn_entries--; :220 offset_lfn = lfn_entries \* MSDOS_LFN_LEN_PER_ENTRY; /_ 
(ord-1)\*13, a uint16 CHAR index _/ :221 
msdos_get_utf16_string_from_long_entry(entry, &lfn_buf\[offset_lfn\], :224 
buf_size - offset_lfn, ...); /_ BYTES(520) - CHARS : units mismatch \*/

The consumer (msdos_misc.c:1075-1078) then, when buf_size \>= 26, 
unconditionally memcpy's 26 bytes (10+12+4) at &lfn_buf\[offset_lfn\]. Because 
offset_lfn is a uint16 index (byte offset = offset_lfn\*2) but the guard 
subtracts it from a byte count, the guard does not protect the buffer:

- ordinal 21 -\> offset_lfn 260 -\> &lfn_buf\[260\] = byte 520 (one past a 
520-byte alloc), guard 520-260=260 \>= 26 passes -\> 26-byte OOB write.
- ordinal \>= 42 -\> 520-offset_lfn underflows size_t -\> guard always passes 
-\> far OOB (ordinal 63 -\> +1092 bytes). The attacker controls both the offset 
(26-byte steps, via the ordinal) and the 26 bytes.

The first-entry sequence/checksum checks (msdos_dir.c:199-201) compare the 
ordinal/checksum to the same entry, so a single crafted 32-byte LFN entry 
(entry\[11\]=0x0F, entry\[0\]=0x40|ord) passes them and triggers on the first 
readdir().

## Impact

Attacker-controlled heap out-of-bounds write from a mounted malicious FAT image 
(SD/USB media or a disk image the device mounts) -\> memory corruption -\> DoS 
and likely code execution. Default FAT mount uses the affected converter.

## Proof of concept

A self-contained host AddressSanitizer PoC compiling the verbatim RTEMS 
consumer + driver logic is attached (poc-standalone/). It reports: 
heap-buffer-overflow WRITE of size 10 ... 0 bytes to the right of 520-byte 
region ... in msdos_get_utf16_string_from_long_entry

We are following coordinated disclosure and will hold public details until a 
fix is released or by mutual agreement. Happy to provide anything else that 
helps.

Best regards

Arash

-- 
View it on GitLab: 
https://gitlab.rtems.org/rtems/rtos/rtems/-/work_items/5656#note_155148
You're receiving this email because of your account on gitlab.rtems.org. 
Unsubscribe from this thread: 
https://gitlab.rtems.org/-/sent_notifications/4-deozfs06b6kreblz62epdypb4-1d/unsubscribe
 | Manage all notifications: https://gitlab.rtems.org/-/profile/notifications | 
Help: https://gitlab.rtems.org/help


_______________________________________________
bugs mailing list
[email protected]
http://lists.rtems.org/mailman/listinfo/bugs

Reply via email to