mirror of
https://github.com/qilingframework/qiling.git
synced 2026-10-12 02:21:40 +00:00
Fix MIPS socket option (SO_*) values
linux_mips_socket_options used generic/incorrect values. MIPS has its own SO_* numbering (arch/mips/include/uapi/asm/socket.h) with the buffer/timeout/ type options in the 0x1000 range. The table listed SO_SNDBUF=0x01, SO_RCVBUF=0x02 (should be 0x1001/0x1002), SO_SND/RCVLOWAT and SO_SND/RCVTIMEO_OLD all wrong, SO_RCVLOWAT=0x04 silently collided with SO_REUSEADDR (Enum alias), and SO_OOBINLINE/SO_REUSEPORT were 0x00. A guest setsockopt(SOL_SOCKET, SO_RCVBUF, ...) (e.g. busybox ping) therefore raised 'Could not convert emulated socket option 4098'. Correct all values to the MIPS uapi and add the missing SO_TYPE/SO_ERROR/SO_ACCEPTCONN/SO_PROTOCOL/ SO_DOMAIN. Add test_elf.ELFTest.test_setsockopt_mips_so_rcvbuf: opens a socket on a MIPS guest and asserts setsockopt(SOL_SOCKET, SO_RCVBUF) succeeds. Self-contained, runs on stock unicorn; fails on dev, passes with the fix. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
a42fb28579
commit
9e21eb9d66
+26
-18
@@ -380,24 +380,32 @@ class linux_mips_socket_level(Enum):
|
||||
# https://docs.huihoo.com/doxygen/linux/kernel/3.7/arch_2mips_2include_2uapi_2asm_2socket_8h_source.html
|
||||
# https://github.com/torvalds/linux/blob/master/arch/mips/include/uapi/asm/socket.h
|
||||
class linux_mips_socket_options(Enum):
|
||||
SO_DEBUG = 0x01
|
||||
SO_REUSEADDR = 0x04
|
||||
SO_KEEPALIVE = 0x08
|
||||
SO_DONTROUTE = 0x10
|
||||
SO_BINDTODEVICE = 0x19
|
||||
SO_BROADCAST = 0x20
|
||||
SO_LINGER = 0x80
|
||||
SO_OOBINLINE = 0x00
|
||||
SO_REUSEPORT = 0x00
|
||||
SO_SNDBUF = 0x01
|
||||
SO_RCVBUF = 0x02
|
||||
SO_SNDLOWAT = 0x03
|
||||
SO_RCVLOWAT = 0x04
|
||||
SO_SNDTIMEO_OLD = 0x05
|
||||
SO_RCVTIMEO_OLD = 0x06
|
||||
SO_TIMESTAMP_OLD = 0x1d
|
||||
# SO_TIMESTAMPNS_OLD = 0x23
|
||||
# SO_TIMESTAMPING_OLD = 0x25
|
||||
# MIPS uses its own SO_* numbering (arch/mips/include/uapi/asm/socket.h);
|
||||
# the buffer/timeout/type options live in the 0x1000 range, unlike the
|
||||
# generic asm-generic values.
|
||||
SO_DEBUG = 0x0001
|
||||
SO_REUSEADDR = 0x0004
|
||||
SO_KEEPALIVE = 0x0008
|
||||
SO_DONTROUTE = 0x0010
|
||||
SO_BINDTODEVICE = 0x0019
|
||||
SO_BROADCAST = 0x0020
|
||||
SO_LINGER = 0x0080
|
||||
SO_OOBINLINE = 0x0100
|
||||
SO_REUSEPORT = 0x0200
|
||||
SO_TYPE = 0x1008
|
||||
SO_ERROR = 0x1007
|
||||
SO_SNDBUF = 0x1001
|
||||
SO_RCVBUF = 0x1002
|
||||
SO_SNDLOWAT = 0x1003
|
||||
SO_RCVLOWAT = 0x1004
|
||||
SO_SNDTIMEO_OLD = 0x1005
|
||||
SO_RCVTIMEO_OLD = 0x1006
|
||||
SO_ACCEPTCONN = 0x1009
|
||||
SO_PROTOCOL = 0x1028
|
||||
SO_DOMAIN = 0x1029
|
||||
SO_TIMESTAMP_OLD = 0x001d
|
||||
# SO_TIMESTAMPNS_OLD = 0x0023
|
||||
# SO_TIMESTAMPING_OLD = 0x0025
|
||||
SO_TIMESTAMP_NEW = 0x3f
|
||||
SO_TIMESTAMPNS_NEW = 0x40
|
||||
SO_TIMESTAMPING_NEW = 0x41
|
||||
|
||||
@@ -404,6 +404,33 @@ class ELFTest(unittest.TestCase):
|
||||
ql.run()
|
||||
del ql
|
||||
|
||||
def test_setsockopt_mips_so_rcvbuf(self):
|
||||
# MIPS uses its own SO_* numbering (SO_RCVBUF = 0x1002, not the generic
|
||||
# 0x08). The MIPS socket-option table had the wrong values, so e.g.
|
||||
# busybox ping's setsockopt(SOL_SOCKET, SO_RCVBUF, ...) raised
|
||||
# NotImplementedError ("Could not convert emulated socket option 4098").
|
||||
from qiling.const import QL_ENDIAN
|
||||
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)
|
||||
|
||||
AF_INET, SOCK_DGRAM = 2, 2
|
||||
SOL_SOCKET, SO_RCVBUF = 0xffff, 0x1002 # MIPS values
|
||||
|
||||
fd = ql_syscall_socket(ql, AF_INET, SOCK_DGRAM, 0)
|
||||
self.assertGreaterEqual(fd, 0)
|
||||
|
||||
base = 0x100000
|
||||
ql.mem.map(base, 0x1000)
|
||||
ql.mem.write_ptr(base, 16384, 4) # requested SO_RCVBUF size
|
||||
|
||||
# must map SO_RCVBUF (0x1002) to the host option and succeed, not raise
|
||||
self.assertEqual(ql_syscall_setsockopt(ql, fd, SOL_SOCKET, SO_RCVBUF, base, 4), 0)
|
||||
|
||||
del ql
|
||||
|
||||
def test_elf_linux_arm_static(self):
|
||||
ql = Qiling(["../examples/rootfs/arm_linux/bin/arm_hello_static"], "../examples/rootfs/arm_linux", verbose=QL_VERBOSE.DEFAULT)
|
||||
all_mem = ql.mem.save()
|
||||
|
||||
Reference in New Issue
Block a user