The checked declaration of bsearch is:
https://github.com/microsoft/checkedc/blob/4e6e0e489a57a68b1c8ad19b6d07a6797f286cbe/include/stdlib_checked.h#L90-L95
The caller is supposed to pass size = sizeof(T), but nothing in the checked declaration expresses this constraint. If the size parameter is too small but nmemb * size is correct, then bsearch may call compar with an argument that points into the middle of a T object, violating type safety, which may lead to a violation of spatial memory safety. (I'd guess that qsort has an analogous problem, but I haven't tested it. Also, memcpy could be abused to overwrite part of a pointer in the destination memory block, leaving an invalid pointer. We should probably review all generic functions in the Checked C headers for problems of this nature.)
For example, the following code compiles with no warnings and generates a segmentation fault at runtime:
Once the parser crash is fixed, I guess the compiler would need to be enhanced to allow sizeof(T) in a _Where clause and instantiate T at each call site.
This issue was copied from https://github.com/microsoft/checkedc/issues/454
The checked declaration of
bsearch
is: https://github.com/microsoft/checkedc/blob/4e6e0e489a57a68b1c8ad19b6d07a6797f286cbe/include/stdlib_checked.h#L90-L95 The caller is supposed to passsize = sizeof(T)
, but nothing in the checked declaration expresses this constraint. If thesize
parameter is too small butnmemb * size
is correct, thenbsearch
may callcompar
with an argument that points into the middle of aT
object, violating type safety, which may lead to a violation of spatial memory safety. (I'd guess thatqsort
has an analogous problem, but I haven't tested it. Also,memcpy
could be abused to overwrite part of a pointer in the destination memory block, leaving an invalid pointer. We should probably review all generic functions in the Checked C headers for problems of this nature.)For example, the following code compiles with no warnings and generates a segmentation fault at runtime:
I hoped we might be able to fix this by adding a
_Where
clause (once_Where
clauses are fully implemented in the compiler), something like this:Unfortunately, this declaration generates a compile error about
T
being an incomplete type and then crashes the parser:Once the parser crash is fixed, I guess the compiler would need to be enhanced to allow
sizeof(T)
in a_Where
clause and instantiateT
at each call site.