DragonFlyBSD Kernel Audit
DF-0900 / run.log
← back to finding ↓ download raw
DF-0900 harness: krpc_subr.c:415-428 signed-int overflow demo
sizeof(struct rpc_reply) = 24  (kernel len initial value)
RPCAUTH_MAXSIZ            = 400  (the bound the code lacks)

authlen      len_after_add          len_after_align        m_adj_req_len          single-mbuf m_len
0x00000000   24                     24                     24                     76   benign (no overflow)
0x00000190   424                    424                    424                    0   exactly RPCAUTH_MAXSIZ (would be allowed by fix)
0x00000191   425                    428                    428                    0   just over RPCAUTH_MAXSIZ (fix -> EBADRPC)
0x7fffffff   -2147483625            -2147483624            -2147483624            0   authlen = INT_MAX
0x7fffffe8   -2147483648            -2147483648            -2147483648            2147483748   authlen = 0x7FFFFFE8  (cited overflow trigger)
  ** BUG FIRES: sizeof_reply(24) + authlen(0x7FFFFFE8) = 0x80000000 = INT_MIN (signed overflow, UB)
  ** (len+3)&~3 = INT_MIN, passed to m_adj() as req_len.
  ** m_len corrupted: 100 -> 2147483748 (OOB on next mbuf op)
0x80000000   -2147483624            -2147483624            -2147483624            0   authlen = 0x80000000
0xffffffff   23                     24                     24                     76   authlen = 0xFFFFFFFF  (max u32)

Verdict: the cited path performs signed `int` arithmetic on an
attacker-controlled u_int32_t (`authlen`) without any upper bound.
For authlen >= 0x7FFFFFE8 the sum overflows to INT_MIN/UB.
The kernel's own NFS socket path (sys/vfs/nfs/nfs_socket.c:2347,2385)
already guards this with `if (len < 0 || len > RPCAUTH_MAXSIZ)`;
krpc_subr.c:425 omits that guard.
RUN_EXIT=0