Thread stuck when emulating a tftpd binary from firmware
Describe the bug
When trying to emulate a tftpd binary from firmware, it seems that the thread stuck when set multithread=True. Here are some outputs.
... // too many output like this
[+] [Thread 2000] Scheduled from 0xffff0fc0.
[+] [Thread 2000] Suspended at 0xffff0fc0
[+] [Thread 2000] Saved context. c13_c0_3=0x778caa00
[+] [Thread 2000] Call sched_cb: <function QlLinuxThread._default_sched_cb at 0x7fc31e132820>
[+] [Thread 2000] Set c13_c0_3 to 0x778caa00
[+] [Thread 2000] Restored context. c13_c0_3=0x778caa00
[+] [Thread 2000] Scheduled from 0xffff0fc0.
[+] [Thread 2000] Suspended at 0xffff0fc0
[+] [Thread 2000] Saved context. c13_c0_3=0x778caa00
[+] [Thread 2000] Call sched_cb: <function QlLinuxThread._default_sched_cb at 0x7fc31e132820>
[+] [Thread 2000] Set c13_c0_3 to 0x778caa00
[+] [Thread 2000] Restored context. c13_c0_3=0x778caa00
[+] [Thread 2000] Scheduled from 0xffff0fc0.
[+] [Thread 2000] Suspended at 0xffff0fc0
[+] [Thread 2000] Saved context. c13_c0_3=0x778caa00
[+] [Thread 2000] Call sched_cb: <function QlLinuxThread._default_sched_cb at 0x7fc31e132820>
[+] [Thread 2000] Set c13_c0_3 to 0x778caa00
[+] [Thread 2000] Restored context. c13_c0_3=0x778caa00
[+] [Thread 2000] Scheduled from 0xffff0fc0.
[+] [Thread 2000] Suspended at 0xffff0fc0
[+] [Thread 2000] Saved context. c13_c0_3=0x778caa00
[+] [Thread 2000] Call sched_cb: <function QlLinuxThread._default_sched_cb at 0x7fc31e132820>
[+] [Thread 2000] Set c13_c0_3 to 0x778caa00
[+] [Thread 2000] Restored context. c13_c0_3=0x778caa00
[+] [Thread 2000] Scheduled from 0xffff0fc0.
[+] [Thread 2000] Suspended at 0xffff0fc0
[+] [Thread 2000] Saved context. c13_c0_3=0x778caa00
[+] [Thread 2000] Call sched_cb: <function QlLinuxThread._default_sched_cb at 0x7fc31e132820>
[+] [Thread 2000] Set c13_c0_3 to 0x778caa00
[+] [Thread 2000] Restored context. c13_c0_3=0x778caa00
[+] [Thread 2000] Scheduled from 0xffff0fc0.
[+] [Thread 2000] Suspended at 0xffff0fc0
[+] [Thread 2000] Saved context. c13_c0_3=0x778caa00
[+] [Thread 2000] Call sched_cb: <function QlLinuxThread._default_sched_cb at 0x7fc31e132820>
[+] [Thread 2000] Set c13_c0_3 to 0x778caa00
[+] [Thread 2000] Restored context. c13_c0_3=0x778caa00
[+] [Thread 2000] Scheduled from 0xffff0fc0.
[+] [Thread 2000] Suspended at 0xffff0fc0
[+] [Thread 2000] Saved context. c13_c0_3=0x778caa00
... // too many output like this
After Ctrl+C, the traceback is like the following. It seems that it got stuck in self._prepare_lib_patch(), and never returned from it.
Traceback (most recent call last):
File "qiling_demo.py", line 2176, in <module>
cisco_ip_phone()
File "qiling_demo.py", line 119, in cisco_ip_phone
ql.run()
File "~/qiling/qiling/core.py", line 587, in run
self.os.run()
File "~/qiling/qiling/os/linux/linux.py", line 141, in run
thread_management.run()
File "~/qiling/qiling/os/linux/thread.py", line 604, in run
previous_thread = self._prepare_lib_patch()
File "~/qiling/qiling/os/linux/thread.py", line 585, in _prepare_lib_patch
gevent.joinall([self.main_thread], raise_error=True)
And here is the output from qemu user mode.
~/test_rootfs$ qemu-arm-static -L . ./tftpd -h
usage: tftpd -t<ip> {-i<slot> -M -u<userid> -g<groupid>} [src] [dest] [-Huge]
ip = tftp server
i = imgui statistics slot
Huge = allow huge 8MB file size
M = image related download
u = userid (numeric)
g = groupid (numeric)
src = source file on tftp server
dst = local file destination
Sample Code
rootfs = "/home/cq/test_rootfs"
path = os.path.join(rootfs, "tftpd")
ql = Qiling([path, "-h"], rootfs, console=True, verbose=QL_VERBOSE.DEBUG, log_file="tftp.log", multithread=True)
ql.run()
Additional context The qiling version is latest.
$ qltool --version
qltool for Qiling 1.4.3-dev, using Unicorn 2.0.6
And the example rootfs is attached. test_rootfs.zip
You can set multithread=False, and find that syscall num 983042 has not been implemented exception.
@newthis As to the syscall num 983042, there is a syscall number typo, I have opened https://github.com/qilingframework/qiling/pull/1115 to fix it.
You can set multithread=False
Try to set multithread=False will cause another common issue (like "NoneType has no attribute cur_thread") in futex() syscall. Currently, I hook the futex() syscall with a custom function, then setting multithread=False works well.
Anyway, I believe there is something wrong with the thread management implementation, which should be fixed.
Close for now.
We updated the codebase for Qiling and Unicorn since this issue being posted.
Feel free to try the latest version.