trailofbits / polytracker

An LLVM-based instrumentation tool for universal taint tracking, dataflow analysis, and tracing.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Current DFSAN instrumentation fails to track certain patterns.

hbrodin opened this issue · comments

We have a specific case where taint tracking gets lost.

#include <stdio.h>
#include <string.h>
static unsigned char tab[256][8];

void
fail(unsigned char *dp, unsigned char *sp)
{
	memcpy(dp, tab[*sp++], 8);
}


int main(int argc, char* argv[]) {

  for (unsigned i=0;i<256;i++) {
    for (unsigned j=0;j<8;j++) {
      tab[i][j] = (unsigned char)(i*j);
    }
  }
  unsigned char dp[8];
  FILE* f = fopen(argv[1], "rb");
  unsigned char sp;
  fread(&sp, 1, sizeof(sp), f);
  fclose(f);


  fail(dp, &sp);

  f = fopen("reproducer.out.bin", "wb");
  fwrite(dp, 1, sizeof(dp), f);
  fclose(f);
  return 0;
}

The problem we are seeing is that sp is tainted when it reaches fail but the memcpy looses track of it because of the dfsan implementation of memcpy:

SANITIZER_INTERFACE_ATTRIBUTE
void *__dfsw_memcpy(void *dest, const void *src, size_t n,
                    dfsan_label dest_label, dfsan_label src_label,
                    dfsan_label n_label, dfsan_label *ret_label) {
  *ret_label = dest_label;
  return dfsan_memcpy(dest, src, n);
}

It will only copy the source taint labels to dest taint labels. In our case, given that tab is not tainted at all we get dest as untainted. For our current use case we handle it via #6422. That is not ideal for the general case though.