qiling icon indicating copy to clipboard operation
qiling copied to clipboard

Thread stuck when emulating a tftpd binary from firmware

Open cq674350529 opened this issue 3 years ago • 2 comments

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

cq674350529 avatar Mar 18 '22 03:03 cq674350529

You can set multithread=False, and find that syscall num 983042 has not been implemented exception.

newthis avatar Mar 22 '22 07:03 newthis

@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.

cq674350529 avatar Mar 22 '22 07:03 cq674350529

Close for now.

We updated the codebase for Qiling and Unicorn since this issue being posted.

Feel free to try the latest version.

xwings avatar Oct 06 '22 03:10 xwings