Paper review: Intel's Advanced Threat Research Innovation Data Fortify
Sun 19 March 2023 — download

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 dst or src are, and abort should dst+size or src+size be 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 memcpy depends 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.