bug: to_disk uses dirname() which may modify its argument (POSIX undefined) #42

Closed
opened 2026-07-20 14:58:55 +02:00 by TapTap · 0 comments
Owner

In src/shared/file.c:412-418, the to_disk function uses dirname() which has platform-dependent behavior:

bool to_disk(const char* path, const void* data, unsigned long long data_size) {
  char* directory = str_dup(path);
  char* dir_to_free = directory;
  directory = dirname(directory);
  if (!mkdir_r(directory)) { ... }

According to POSIX, dirname() may modify its argument. While the code does pass a duplicate (via str_dup), the behavior of dirname() varies between platforms:

  • On Linux (glibc), dirname() does NOT modify its input and returns a pointer to a static buffer (NOT the input pointer)
  • On BSD/macOS, dirname() MAY modify the input buffer
  • The code passes the dirname() return to mkdir_r(), which is correct, but the semantics are fragile

Additionally, after calling dirname(), the original directory pointer should NOT be freed since it may point to a static buffer (on Linux) rather than the original duplicated allocation.

Fix: Either use a portable implementation or avoid dirname() entirely by implementing directory extraction in-path.

Severity: low

In src/shared/file.c:412-418, the to_disk function uses dirname() which has platform-dependent behavior: ```c bool to_disk(const char* path, const void* data, unsigned long long data_size) { char* directory = str_dup(path); char* dir_to_free = directory; directory = dirname(directory); if (!mkdir_r(directory)) { ... } ``` According to POSIX, dirname() may modify its argument. While the code does pass a duplicate (via str_dup), the behavior of dirname() varies between platforms: - On Linux (glibc), dirname() does NOT modify its input and returns a pointer to a static buffer (NOT the input pointer) - On BSD/macOS, dirname() MAY modify the input buffer - The code passes the dirname() return to mkdir_r(), which is correct, but the semantics are fragile Additionally, after calling dirname(), the original `directory` pointer should NOT be freed since it may point to a static buffer (on Linux) rather than the original duplicated allocation. Fix: Either use a portable implementation or avoid dirname() entirely by implementing directory extraction in-path. Severity: low
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: TapTap/FastSync#42