<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
<html lang="en" style="--code-editor-font: var(--default-mono-font, "GitLab Mono"), JetBrains Mono, Menlo, DejaVu Sans Mono, Liberation Mono, Consolas, Ubuntu Mono, Courier New, andale mono, lucida console, monospace;">
<head>
<meta content="text/html; charset=UTF-8" http-equiv="Content-Type">
<title>
GitLab
</title>
<style data-premailer="ignore" type="text/css">
a { color: #1068bf; }
</style>
<style>img {
max-width: 100%; height: auto;
}
body {
font-size: .875rem;
}
body {
-webkit-text-shadow: hsla(0,0%,100%,.01) 0 0 1px;
}
body {
font-family: "GitLab Sans",-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Noto Sans",Ubuntu,Cantarell,"Helvetica Neue",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji"; font-size: inherit;
}
</style>
</head>
<body style="font-size: inherit; -webkit-text-shadow: hsla(0,0%,100%,.01) 0 0 1px; font-family: "GitLab Sans",-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Noto Sans",Ubuntu,Cantarell,"Helvetica Neue",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";">
<div class="content">
<p style="color: #777777;">
<a href="https://gitlab.rtems.org/Arash">Arash -</a>
<a href="https://gitlab.rtems.org/rtems/rtos/rtems/-/work_items/5656#note_155148">commented</a>:
</p>
<div class="md" style="position: relative; z-index: 1; color: #3a383f; word-wrap: break-word;">
<p dir="auto" style="color: #3a383f; margin: 0px 0px 1rem;" align="initial">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.</p>
<p dir="auto" style="color: #3a383f; margin: 0px 0px 1rem;" align="initial">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</p>
<p dir="auto" style="color: #3a383f; margin: 0px 0px 1rem;" align="initial"><a href="https://gitlab.rtems.org/-/project/26/uploads/5f70561288677d7986082da031f61492/poc-rtems-fs.zip" data-canonical-src="/uploads/5f70561288677d7986082da031f61492/poc-rtems-fs.zip" data-link="true" class="gfm" style="margin-top: 0px;">poc-rtems-fs.zip</a></p>
<p dir="auto" style="color: #3a383f; margin: 0px 0px 1rem;" align="initial">misc.c); default UTF-16 converter (msdos_conv_default.c, 520-byte buffer). Version: current HEAD (<a href="https://gitlab.rtems.org/rtems/rtos/rtems/-/commit/48404723193c24f9d38948e520aa3d0f7a492544" title="shared/u-boot: Cleanup unused function" class="gfm gfm-commit has-tooltip" data-original="4840472" data-link="false" data-link-reference="false" data-commit="48404723193c24f9d38948e520aa3d0f7a492544" data-project="26" data-container="body" data-placement="top" data-reference-type="commit" style="font-family: "GitLab Mono", "JetBrains Mono", "Menlo", "DejaVu Sans Mono", "Liberation Mono", "Consolas", "Ubuntu Mono", "Courier New", "andale mono", "lucida console", monospace; font-variant-ligatures: none; font-size: 95%; margin-top: 0px;">48404723</a>) 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 <span data-escaped-char="">~</span>7.8 High (est.) AV:L/AC:L/PR:N/UI:N/S:U/C:L/I:H/A:H.</p>
<h2 dir="auto" style="margin-top: 20px; margin-bottom: 10px;" align="initial">Root cause</h2>
<p dir="auto" style="color: #3a383f; margin: 0px 0px 1rem;" align="initial">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:</p>
<p dir="auto" style="color: #3a383f; margin: 0px 0px 1rem;" align="initial">:184 lfn_entries = entry[0] & MSDOS_LAST_LONG_ENTRY_MASK; /* 0..63 <em style="margin-top: 0px;">/ :219 lfn_entries--; :220 offset_lfn = lfn_entries * MSDOS_LFN_LEN_PER_ENTRY; /</em> (ord-1)*13, a uint16 CHAR index <em>/ :221 msdos_get_utf16_string_from_long_entry(entry, &lfn_buf[offset_lfn], :224 buf_size - offset_lfn, ...); /</em> BYTES(520) - CHARS : units mismatch */</p>
<p dir="auto" style="color: #3a383f; margin: 0px 0px 1rem;" align="initial">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:</p>
<ul dir="auto" style="text-align: initial; list-style-type: disc; margin: 0px 0px 1rem; padding: 0;">
<li style="margin-top: 0px; line-height: 1.6em; margin-left: 25px; padding-left: 3px;">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.</li>
<li style="line-height: 1.6em; margin-left: 25px; padding-left: 3px;">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.</li>
</ul>
<p dir="auto" style="color: #3a383f; margin: 0px 0px 1rem;" align="initial">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().</p>
<h2 dir="auto" style="margin-top: 20px; margin-bottom: 10px;" align="initial">Impact</h2>
<p dir="auto" style="color: #3a383f; margin: 0px 0px 1rem;" align="initial">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.</p>
<h2 dir="auto" style="margin-top: 20px; margin-bottom: 10px;" align="initial">Proof of concept</h2>
<p dir="auto" style="color: #3a383f; margin: 0px 0px 1rem;" align="initial">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</p>
<p dir="auto" style="color: #3a383f; margin: 0px 0px 1rem;" align="initial">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.</p>
<p dir="auto" style="color: #3a383f; margin: 0px 0px 1rem;" align="initial">Best regards</p>
<p dir="auto" style="color: #3a383f; margin: 0px;" align="initial">Arash</p>
</div>
</div>
<div class="footer" style="margin-top: 10px;">
<p style="font-size: small; color: #626168;">
—
<br>
<a href="https://gitlab.rtems.org/rtems/rtos/rtems/-/work_items/5656#note_155148">View it on GitLab</a>.
<br>
You're receiving this email because of your account on <a target="_blank" rel="noopener noreferrer" href="https://gitlab.rtems.org">gitlab.rtems.org</a>. <a href="https://gitlab.rtems.org/-/sent_notifications/4-deozfs06b6kreblz62epdypb4-1d/unsubscribe" target="_blank" rel="noopener noreferrer">Unsubscribe</a> from this thread · <a href="https://gitlab.rtems.org/-/profile/notifications" target="_blank" rel="noopener noreferrer" class="mng-notif-link">Manage all notifications</a> · <a href="https://gitlab.rtems.org/help" target="_blank" rel="noopener noreferrer" class="help-link">Help</a>
<span style="color: transparent; font-size: 0; display: none; overflow: hidden; opacity: 0; width: 0; height: 0; max-width: 0; max-height: 0;">
Notification message regarding https://gitlab.rtems.org/rtems/rtos/rtems/-/work_items/5656#note_155148 at 1784742526
</span>
<script type="application/ld+json">{"@context":"http://schema.org","@type":"EmailMessage","action":{"@type":"ViewAction","name":"View Work item","url":"https://gitlab.rtems.org/rtems/rtos/rtems/-/work_items/5656#note_155148"}}</script>
</p>
</div>
</body>
</html>