Skip to content

Commit bda1ef2

Browse files
committed
fw/filesystem: fix crash when temp file closes while original name is open
When closing a temp file, pfs_close() calls pfs_remove() on the original filename to delete it from flash. However, if another fd had the same filename open as a non-temp file, pfs_remove() would find that fd with status=IN_USE and crash with "Cannot delete X, it is currently in use". This could happen in scenarios like: 1. A temp file is created for "app_comm" (is_tmp=TRUE) 2. Someone opens "app_comm" as regular file (is_tmp=FALSE) 3. Temp file is closed -> pfs_remove("app_comm") finds the fd from step 2 4. Crash because that fd is still IN_USE Fix this by checking in file_found_in_cache() whether a temp file with the same name is already in use when opening a non-temp file. If so, return E_BUSY to prevent creating conflicting fd entries. Signed-off-by: Joshua Jun <[email protected]>
1 parent dd8e923 commit bda1ef2

File tree

1 file changed

+13
-1
lines changed
  • src/fw/services/normal/filesystem

1 file changed

+13
-1
lines changed

src/fw/services/normal/filesystem/pfs.c

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1413,7 +1413,8 @@ status_t pfs_close(int fd) {
14131413

14141414
File *f = &PFS_FD(fd).file;
14151415
if (f->is_tmp) {
1416-
// TODO: For safety, could disallow this op if user has orig file hdl open
1416+
// Note: file_found_in_cache() now prevents opening a non-temp file while a
1417+
// temp file with the same name is in use, so pfs_remove() here is safe.
14171418
pfs_remove(f->name);
14181419
// Note: if we reboot before updating the tmp state flag to done, the tmp &
14191420
// original file will be deleted. This is an extremely small window, but
@@ -1716,6 +1717,17 @@ static NOINLINE bool file_found_in_cache(const char *name, uint8_t op_flags, int
17161717
goto cleanup;
17171718
}
17181719

1720+
// When opening a non-temp file, check if a temp file with the same name is in use.
1721+
// If so, block the open to prevent crashes when the temp file is later closed
1722+
// (pfs_close for temp files calls pfs_remove on the original filename).
1723+
if (!is_tmp) {
1724+
int tmp_fd;
1725+
if (get_avail_fd(name, &tmp_fd, true) == FDBusy) {
1726+
res = E_BUSY;
1727+
goto cleanup;
1728+
}
1729+
}
1730+
17191731
File *file = &PFS_FD(fd).file;
17201732

17211733
// settings for cached & new fds

0 commit comments

Comments
 (0)