The following reproducer will cause a UAF of a previously allocated memory in bpf.
You can reproduce with linux kernel master, or 4.6-rc6 4.6-rc7 and maybe other kernel versions.
In the reproducer there is also a log of the UAF with KASAN of the kernel running on qemu x64
Thanks
Marco
Reproducer C file:
==================
2016/05/12) compiled with KASAN to see the log
#include <stdio.h>
#include <unistd.h>
#include <sys/syscall.h>
#include <string.h>
#include <stdint.h>
#include <pthread.h>
#ifndef SYS_mmap
#define SYS_mmap 9
#endif
#ifndef SYS_bpf
#define SYS_bpf 321
#endif
long r[6];
int main( int argc, char **argv)
{
printf( "--beginning of program\n" );
while (1) {
pid_t pid = fork();
if (pid == 0)
{
memset(r, -1, sizeof (r));
r[0] = syscall(SYS_mmap, 0x20000000ul, 0xf000ul, 0x3ul, 0x32ul, 0xfffffffffffffffful, 0x0ul);
*(uint32_t*)0x20006eea = (uint32_t)0x6;
*(uint32_t*)0x20006eee = (uint32_t)0x4;
*(uint32_t*)0x20006ef2 = (uint32_t)0x54d1;
*(uint32_t*)0x20006ef6 = (uint32_t)0xc93;
r[5] = syscall(SYS_bpf, 0x0ul, 0x20006eeaul, 0x10ul, 0, 0, 0);
return 0;
}
else if (pid > 0)
{
memset(r, -1, sizeof (r));
r[0] = syscall(SYS_mmap, 0x20000000ul, 0xf000ul, 0x3ul, 0x32ul,0xfffffffffffffffful, 0x0ul);
*(uint32_t*)0x20006eea = (uint32_t)0x6;
*(uint32_t*)0x20006eee = (uint32_t)0x4;
*(uint32_t*)0x20006ef2 = (uint32_t)0x54d1;
*(uint32_t*)0x20006ef6 = (uint32_t)0xc93;
r[5] = syscall(SYS_bpf, 0x0ul, 0x20006eeaul, 0x10ul, 0, 0, 0);
int returnStatus;
waitpid(pid, &returnStatus, 0);
printf( "collected child\n" );
}
else
{
printf( "fork() failed!\n" );
return 1;
}
}
printf( "--end of program--\n" );
return 0;
}
=====================
|