Add wrappers for _chk() functions
Nobody has claimed this yet.
- Dominant language
- C
- Stars
- 122
- Forks
- 34
- PR merge metrics
- No merged PRs in 30d
Description
Discovered the hard way, libc has a number of _chk() wrappers, like __getcwd_chk(), that can be used to detect and exit with error on potential buffer overruns. The compiler can sometimes map an existing call like getcwd to its __getcwd_chk symbol if the conditions are right. For example if it knows the size of the buffer at compile time but not the size of the incoming string / data.
There are a number of these functions related to file system calls, perhaps more than what this list shows:
>>: nm /usr/lib/libc.so.6 | grep _chk
001179b0 t __GI___vdprintf_chk
00115bf0 t __GI___vfprintf_chk
001170d0 t __GI___vfwprintf_chk
001159a0 t ___fprintf_chk
00115bf0 t ___vfprintf_chk
00117980 T __dprintf_chk
001160e0 T __fgets_chk
00116260 T __fgets_unlocked_chk
001171f0 T __fgetws_chk
00117370 T __fgetws_unlocked_chk
001159a0 T __fprintf_chk
00116640 T __fread_chk
001167b0 T __fread_unlocked_chk
00116e80 T __fwprintf_chk
00116580 T __getcwd_chk
00115d10 T __gets_chk
00116530 T __getwd_chk
00117df0 T __poll_chk
00117e30 T __ppoll_chk
001163b0 T __pread64_chk
00116360 T __pread_chk
00116300 T __read_chk
00116490 T __readlink_chk
001164f0 T __readlinkat_chk
001165c0 T __realpath_chk
001179b0 T __vdprintf_chk
00115bf0 T __vfprintf_chk
001170d0 T __vfwprintf_chk
It may be necessary to add corresponding wrappers for each.
Some background on where this showed up: https://github.com/LLNL/UnifyFS/pull/497
The prototype for this other function is:
__getcwd_chk(char* buf, size_t size, size_t buflen)
It is supposed to check that size <= buflen and abort with an exit() if not to prevent buffer overruns:
http://refspecs.linux-foundation.org/LSB_4.0.0/LSB-Core-generic/LSB-Core-generic/libc---getcwd-chk-1.html
For my buffer in the test code, I am using a hard coded char path[64]. Thus, the compiler knows I have a 64-char buffer. When I then have code like the following:
size_t len = 25;
getcwd(path, len);
The compiler can determine at compile time that there can be no buffer overrun, since it knows the value of len (25) is less than the size of my buffer (64). In this case, it knows it's fine to call getcwd.
In the case of:
size_t len = strlen(str);
getcwd(path, len)
then the value of len is not determined until run time. The compiler still knows I have a buffer of 64 characters, though, so it can map this call to __getcwd_chk(path, len, 64). That's a safe thing to do since it prevents a potential buffer overrun.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
No repository files or tests are named. Start by locating the existing libc/system-call wrapper entry points, then compare them with the listed _chk symbols, beginning with __getcwd_chk and its stated prototype. Done means the necessary filesystem-related wrappers are identified and added with the documented buffer-size checking behavior.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- c
- Domain
- operating-systems
- Issue type
- Feature
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100