MIPS socket option (SO_*) values are wrong — setsockopt fails (e.g. busybox ping)
Describe the bug
linux_mips_socket_options (qiling/os/posix/const.py) uses generic/incorrect SO_* values. MIPS has its own numbering (arch/mips/include/uapi/asm/socket.h) where the buffer/timeout/type options live in the 0x1000 range, unlike the asm-generic values used by most arches. The table is wrong in several places:
| option |
table has |
MIPS uapi |
SO_SNDBUF |
0x01 |
0x1001 |
SO_RCVBUF |
0x02 |
0x1002 |
SO_SNDLOWAT |
0x03 |
0x1003 |
SO_RCVLOWAT |
0x04 |
0x1004 |
SO_SNDTIMEO_OLD |
0x05 |
0x1005 |
SO_RCVTIMEO_OLD |
0x06 |
0x1006 |
SO_OOBINLINE |
0x00 |
0x0100 |
SO_REUSEPORT |
0x00 |
0x0200 |
SO_RCVLOWAT = 0x04 also silently collides with SO_REUSEADDR = 0x04 (it becomes an Enum alias), and SO_TYPE/SO_ERROR are missing entirely.
Consequently a guest setsockopt(SOL_SOCKET, SO_RCVBUF, ...) aborts emulation:
NotImplementedError: Could not convert emulated socket option 4098 to a socket option name
(4098 == 0x1002 == SO_RCVBUF on MIPS.) This is hit by ordinary programs — e.g. busybox ping sets SO_RCVBUF/SO_SNDBUF right after creating its socket.
Repro (Python)
from qiling import Qiling
from qiling.const import QL_ARCH, QL_OS, QL_ENDIAN, QL_VERBOSE
from qiling.os.posix.syscall.socket import ql_syscall_socket, ql_syscall_setsockopt
ql = Qiling(code=b"\x00\x00\x00\x00", archtype=QL_ARCH.MIPS, ostype=QL_OS.LINUX,
endian=QL_ENDIAN.EB, rootfs="examples/rootfs/mips32_linux", verbose=QL_VERBOSE.OFF)
fd = ql_syscall_socket(ql, 2, 2, 0) # AF_INET, SOCK_DGRAM
base = 0x100000
ql.mem.map(base, 0x1000)
ql.mem.write_ptr(base, 16384, 4)
# SOL_SOCKET=0xffff, SO_RCVBUF=0x1002 on MIPS
ql_syscall_setsockopt(ql, fd, 0xffff, 0x1002, base, 4)
Without the fix this raises NotImplementedError: Could not convert emulated socket option 4098.
Expected behavior
setsockopt with the MIPS SO_* values should map to the host option and succeed, matching the kernel's MIPS SO_* numbering.
Environment
A fix (correct the SO_* values + add the missing ones, with a regression test) is proposed in the linked PR.
MIPS socket option (
SO_*) values are wrong —setsockoptfails (e.g.busybox ping)Describe the bug
linux_mips_socket_options(qiling/os/posix/const.py) uses generic/incorrectSO_*values. MIPS has its own numbering (arch/mips/include/uapi/asm/socket.h) where the buffer/timeout/type options live in the0x1000range, unlike the asm-generic values used by most arches. The table is wrong in several places:SO_SNDBUF0x010x1001SO_RCVBUF0x020x1002SO_SNDLOWAT0x030x1003SO_RCVLOWAT0x040x1004SO_SNDTIMEO_OLD0x050x1005SO_RCVTIMEO_OLD0x060x1006SO_OOBINLINE0x000x0100SO_REUSEPORT0x000x0200SO_RCVLOWAT = 0x04also silently collides withSO_REUSEADDR = 0x04(it becomes anEnumalias), andSO_TYPE/SO_ERRORare missing entirely.Consequently a guest
setsockopt(SOL_SOCKET, SO_RCVBUF, ...)aborts emulation:(
4098 == 0x1002 == SO_RCVBUFon MIPS.) This is hit by ordinary programs — e.g.busybox pingsetsSO_RCVBUF/SO_SNDBUFright after creating its socket.Repro (Python)
Without the fix this raises
NotImplementedError: Could not convert emulated socket option 4098.Expected behavior
setsockoptwith the MIPSSO_*values should map to the host option and succeed, matching the kernel's MIPSSO_*numbering.Environment
IPPROTO_TCP).A fix (correct the
SO_*values + add the missing ones, with a regression test) is proposed in the linked PR.