Fishwaldo opened a new pull request, #19731:
URL: https://github.com/apache/nuttx/pull/19731
## Summary
* Creating two files with short lowercase names on a FAT volume with long
file name support produces two directory entries with the same blank
name, and both names then open the same file.
* `fat_path2dirname()` marks a parsed name as needing long file name
entries by clearing the first byte of the short name buffer.
`fat_dirnamewrite()` writes the long name entries only while that marker
survives.
* Since commit bc9e1ffb01, a name short enough to fit the 8.3 form is
speculatively re-parsed as a short name. That re-parse fills the short
name buffer with spaces before it examines a single character. When it
then rejects the name, for being lowercase say, the spaces stay behind,
the marker is gone, and the file is created with eleven spaces for a
name: no long name entries, a blank alias.
* Every such file aliases to every other, since every rejected name
converts to the same blank entry. Create `a.txt`, then create `big1`, and
both names now open one file; a directory of them lists as a single
nameless entry.
* The fix restores the marker when the speculative parse fails. It also
hands that parse a real terminator variable: on success it writes through
the pointer it is given, and it was given NULL.
* No related issue filed.
## Impact
* Is new feature added? Is existing feature changed? **NO.** Bug fix, a
regression from bc9e1ffb01.
* Impact on user? **YES, positive, and please read this one.** Any
application that writes two lowercase short-named files and reads the
first back currently gets the second's contents. Volumes already written
by an affected build contain blank-named entries; this change stops new
ones being created but does not repair existing directories, which need
`fsck` or a reformat.
* Impact on build? **NO.**
* Impact on hardware? **NO.** Filesystem code, architecture-independent.
* Impact on documentation? **NO.**
* Impact on security? **Indirectly, yes.** One file silently serving
another
file's contents is a confidentiality and integrity problem for anything
that trusts filenames, even though there is no privilege boundary here.
* Impact on compatibility? **NO.** Correctly-named entries are unchanged,
and uppercase 8.3 names still produce plain short entries with no long
name chain, exactly as before.
* Anything else? The NULL terminator argument is a latent fault that
happens
to be harmless only on platforms where a store to address zero is
tolerated. It is fixed here because it is in the same call.
## Testing
I confirm that changes are verified on local setup and works as intended:
* Build Host: macOS 26.5.1, arm64 (Apple Silicon), xPack riscv-none-elf-gcc
15.2.0
* Target: RISC-V, ESWIN EIC7700X EVB (downstream board port, not yet
upstream), FAT32 on SD, `CONFIG_FAT_LFN=y`
Reproduce by creating a lowercase short name, then a second one. The first
file's name then resolves to the second file:
Testing logs before change:
```
##### CMD 4: echo alpha-42 > /mnt/sd/a.txt
##### END 4 (ok, 1.55s)
##### CMD 5: cat /mnt/sd/a.txt
alpha-42
##### END 5 (ok, 1.61s)
##### CMD 6: ls -l /mnt/sd/a.txt
-rw-rw-rw- 9 /mnt/sd/a.txt
##### END 6 (ok, 1.54s)
##### CMD 7: dd if=/dev/zero of=/mnt/sd/big1 bs=16384 count=64
1048576 bytes (64 blocks) copied, 152000 usec, 6736 KB/s
##### END 7 (ok, 1.57s)
##### CMD 8: cat /mnt/sd/a.txt
##### END 8 (ok, 92.06s)
##### CMD 9: ls -l /mnt/sd/a.txt
-rw-rw-rw- 1048576 /mnt/sd/a.txt
##### END 9 (ok, 1.54s)
##### CMD 10: ls -l /mnt/sd/big1
-rw-rw-rw- 1048576 /mnt/sd/big1
##### END 10 (ok, 1.59s)
##### CMD 11: ls -l /mnt/sd
/mnt/sd:
drw-rw-rw- 0
##### END 11 (ok, 1.53s)
```
`a.txt` was nine bytes and read back `alpha-42`. After `big1` is created,
`a.txt` is 1048576 bytes and reads empty: the two names are one file. The
directory holds a single nameless entry.
Testing logs after change, exercising every filename class in one volume:
```
##### CMD 9: ls -l /mnt/sd
/mnt/sd:
-rw-rw-rw- 6 c.txt
-rw-rw-rw- 6 A.TXT
-rw-rw-rw- 9 averylongfilename.txt
-rw-rw-rw- 6 Mixed.Txt
-rw-rw-rw- 1048576 big1
##### END 9 (ok, 1.54s)
##### CMD 10: cat /mnt/sd/c.txt
lower
##### END 10 (ok, 1.58s)
##### CMD 11: cat /mnt/sd/averylongfilename.txt
longname
##### END 11 (ok, 1.56s)
```
Lowercase, uppercase 8.3, mixed case and over-length names all produce
distinct, correctly named entries, and each reads back its own contents.
The uppercase `A.TXT` still produces a plain short entry with no long name
chain.
Surviving unmount and reboot, with a file added after the remount:
```
##### CMD 3: ls -l /mnt/sd
/mnt/sd:
-rw-rw-rw- 6 c.txt
-rw-rw-rw- 6 A.TXT
-rw-rw-rw- 9 averylongfilename.txt
-rw-rw-rw- 6 Mixed.Txt
-rw-rw-rw- 1048576 big1
-rw-rw-rw- 8 cycle1.txt
##### END 3 (ok, 1.54s)
##### CMD 4: cat /mnt/sd/cycle1.txt
reboot1
##### END 4 (ok, 1.55s)
```
The before and after runs are separate sessions on the bench and use
different filenames; they are not a single matched experiment.
## PR verification Self-Check
* [x] This PR introduces only one functional change.
* [x] I have updated all required description fields above.
* [x] My PR adheres to Contributing Guidelines and Documentation.
* [ ] My PR is still work in progress (not ready for review).
* [x] My PR is ready for review and can be safely merged into a codebase.
---
*Claude (claude-opus-5) assisted with diagnosing this bug and with authoring
the
code comment and this PR description. The commit carries an `Assisted-by:`
tag
per
[CONTRIBUTING.md](https://github.com/apache/nuttx/blob/master/CONTRIBUTING.md)
ยง1.5.*
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]