PDF: 61a95c4d3c51d49e7448e727d5b1462bfa8e566c1e90f411933226d7f79a6a24
Intel's Advanced Threat Research Innovation Data Fortify by Hasarfaty, Shai - Principal Offensive Security Research Engineer at Intel, is a research paper on improving the runtime safety of "dangerous standard C library function such as: memcpy, strcpy, memmove, sprint, strlen, strcat, strncat etc". Apparently, they're so sure of its quality that
This solution is planned to be integrated into Intel® Converged Security and Management Engine (CSE / CSME) as a defense in-depth mitigation in addition to its existing exploitation mitigation."
The basic idea is something like this:
void memcpy(void *dst, void *src, size_t size)
{
verify(dst, size);
verify(src, size);
// actual memcpy implementation
}
- For variables on the stack, the idea is to make use of the stack pointer to get the size of
the stackframe in which
dstorsrcare, and abort shoulddst+sizeorsrc+sizebe larger, respectively. Performance-wise, "In our experiments we found that in practice, real applications usually have a maximum nested tree depth of n=10, while the average nested tree depth is n=3.", without saying on what "real applications" this was done, so I call bullshit on this. - For global variables, the linker is used to get their sizes.
- For variables on the heap, the allocator keeps track of freed pages, with a
per-page inline bitmap to keep track of sub-page-size allocations,
and …… stuff:
In case a page is marked as a “Fragmented” allocation page, in the beginning of the page itself, there is a bitmap that describes all allocations in the page. The bitmap size is 128-byte (1024-bit) where each set bit (“1”) describes a 4-byte allocation. Between each allocation there is a marker of 4-bytes that is marked as “free” (0b) in the byte allocation bitmap. This 4byte marker holds metadata for debugging and overflow detection (marker is verified only during “free” operation). The marker is split into two 16bit parts. The first 16 bits hold the caller information, and the second 16-bits hold a random cookie.
Unfortunately:
- The stack-based implementation come with unpredictable performance impact: the
speed of your
memcpydepends on its callsite. - The global variable one should already be covered by
FORTIFY_SOURCE. - The heap one is late to the heap exploitation game, the 90s called: they wanted their trusted inline metadata back.