Bug 15554 - Crash due to misuse of readdir in cap_readdir plus other misuses of struct dirent
Summary: Crash due to misuse of readdir in cap_readdir plus other misuses of struct di...
Status: NEW
Alias: None
Product: Samba 4.1 and newer
Classification: Unclassified
Component: VFS Modules (show other bugs)
Version: 4.19.4
Hardware: All All
: P5 normal (vote)
Target Milestone: ---
Assignee: Samba QA Contact
QA Contact: Samba QA Contact
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2024-01-09 20:07 UTC by Martin Simmons
Modified: 2024-01-10 22:23 UTC (History)
2 users (show)

See Also:


Attachments
Downstream patch for 4.16 (1.08 KB, patch)
2024-01-10 06:31 UTC, Ralph Böhme
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Martin Simmons 2024-01-09 20:07:01 UTC
While looking at the crash reported in https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=275597, I found some suspicious code in the VFS readdir handers.

1. The crash is caused by the code in cap_readdir (source3/modules/vfs_cap.c), which is problematic because the line:

	memcpy(newdirent, result, sizeof(struct dirent));

fails if (char *)result + sizeof(struct dirent) - 1 is in unmapped memory.  On FreeBSD and Linux, the d_name field in struct dirent is an array of 256 bytes but testing shows that readdir() only guarantees that memory up to (char *)result + result->d_reclen is readable.

2. Possibly the same thing can happen in open_and_sort_dir (source3/modules/vfs_dirsort.c) when it does:

		data->directory_list[total_count] = *dp;

and in shadow_copy_fdopendir and possibly other places.

3. Conversely, on Solaris, the d_name field in struct dirent is an array of 1 byte so the copying code in 2 will not copy the name (as reported for dirsort in bug 8466).

4. The code in cap_readdir allocates newdirent of size sizeof(struct dirent) + newnamelen, so that is double-counting the name bytes on FreeBSD and Linux.
Comment 1 Ralph Böhme 2024-01-10 06:31:27 UTC
Created attachment 18225 [details]
Downstream patch for 4.16