Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix overflow with wait options #1413

Merged
merged 1 commit into from
Dec 14, 2023
Merged

Fix overflow with wait options #1413

merged 1 commit into from
Dec 14, 2023

Conversation

Ninja3047
Copy link

Python expects options to be a signed 32bit integer. The current code will throw the following error in Python when emulating the wait4 syscall with the __WCLONE option (0x80000000).

Traceback (most recent call last):                                                                                                                                                                                  
  File "/nix/store/1l9zwzxgclpfm324h9kyrrp3xv4x7b84-python3-3.11.6-env/lib/python3.11/site-packages/qiling/os/posix/posix.py", line 374, in load_syscall                                                            
    retval = syscall_hook(self.ql, *params)                                                                                                                                                                         
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^                                                                                                                                                                         
  File "/nix/store/1l9zwzxgclpfm324h9kyrrp3xv4x7b84-python3-3.11.6-env/lib/python3.11/site-packages/qiling/os/posix/syscall/wait.py", line 16, in ql_syscall_wait4                                                  
    spid, status, _ = os.wait4(pid, options)                                                                                                                                                                        
                      ^^^^^^^^^^^^^^^^^^^^^^                                                                                                                                                                        
OverflowError: signed integer is greater than maximum 

if I debug the Python implementation of os.wait4, we can see that the error is thrown here when it tries to get the option argument

--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- code:x86:64 ----
    0x7ffff795b2cf 488b38             <convertitem+0x146f>   mov    rdi, QWORD PTR [rax] 
    0x7ffff795b2d2 e8c9870300         <convertitem+0x1472>   call   0x7ffff7993aa0 <PyErr_SetString> 
    0x7ffff795b2d7 e934efffff         <convertitem+0x1477>   jmp    0x7ffff795a210 <convertitem+0x3b0> 
 -> 0x7ffff795b2dc 488b05258b3500     <convertitem+0x147c>   mov    rax, QWORD PTR [rip + 0x358b25] # 0x7ffff7cb3e08
    0x7ffff795b2e3 488d35f69b2b00     <convertitem+0x1483>   lea    rsi, [rip + 0x2b9bf6] # 0x7ffff7c14ee0
    0x7ffff795b2ea 488b38             <convertitem+0x148a>   mov    rdi, QWORD PTR [rax] 
    0x7ffff795b2ed e8ae870300         <convertitem+0x148d>   call   0x7ffff7993aa0 <PyErr_SetString> 
    0x7ffff795b2f2 e919efffff         <convertitem+0x1492>   jmp    0x7ffff795a210 <convertitem+0x3b0> 
    0x7ffff795b2f7 488b4328           <convertitem+0x1497>   mov    rax, QWORD PTR [rbx + 0x28] 
----------------------------------------------------------------------------------------------------------------------------------------------------------------- memory access: $rip+0x358b25 = 0x7ffff7cb3e08 ----
0x7ffff7cb3e08|+0x0000|+000: 0x00007ffff7cca588 <PyExc_OverflowError>  ->  0x00007ffff7cce580 <_PyExc_OverflowError>  ->  0x0000000000000006
0x7ffff7cb3e10|+0x0008|+001: 0x00007ffff7db49e0 <PyODictKeys_Type>  ->  0x0000000000000004
0x7ffff7cb3e18|+0x0010|+002: 0x00007ffff7dba260 <PyDictProxy_Type>  ->  0x000000000000001f
0x7ffff7cb3e20|+0x0018|+003: 0x00007ffff7db83c0 <_PyAsyncGenASend_Type>  ->  0x0000000000000009 ('\t'?)
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- source:Python/getargs.c+742 ----
    737           int *p = va_arg(*p_va, int *);
    738           long ival = PyLong_AsLong(arg);
    739           if (ival == -1 && PyErr_Occurred())
    740               RETURN_ERR_OCCURRED;
    741           else if (ival > INT_MAX) {
*-> 742               PyErr_SetString(PyExc_OverflowError,
    743                               "signed integer is greater than maximum");
    744               RETURN_ERR_OCCURRED;
    745           }
    746           else if (ival < INT_MIN) {
    747               PyErr_SetString(PyExc_OverflowError,
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- threads ----
[Thread Id:1] Name: "python", stopped 0x7ffff795b2dc <convertitem+0x147c> in convertsimple, reason: BREAKPOINT
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- trace ----
[#0] 0x7ffff795b2dc <convertitem+0x147c>
[#1] 0x7ffff795b2dc <convertitem+0x147c>
[#2] 0x7ffff7adeda2 <vgetargskeywordsfast_impl+0x222>
[#3] 0x7ffff7adf58a <_PyArg_ParseStackAndKeywords_SizeT+0x9a>
[#4] 0x7ffff7b690a8 <os_wait4+0x48>
[#5] 0x7ffff7967882 <cfunction_vectorcall_FASTCALL_KEYWORDS+0x52>
[#6] 0x7ffff7a5f143 <PyObject_Vectorcall+0x33>
[#7] 0x7ffff7a5f143 <PyObject_Vectorcall+0x33>
[#8] 0x7ffff78f8802 <_PyEval_EvalFrameDefault+0x40b2>
[#9] 0x7ffff7b2b3aa <_PyEval_Vector+0x12a>
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
gef> p ival
$1 = 0x80000000

Checklist

Which kind of PR do you create?

  • This PR only contains minor fixes.
  • This PR contains major feature update.
  • This PR introduces a new function/api for Qiling Framework.

Coding convention?

  • The new code conforms to Qiling Framework naming convention.
  • The imports are arranged properly.
  • Essential comments are added.
  • The reference of the new code is pointed out.

Extra tests?

  • No extra tests are needed for this PR.
  • I have added enough tests for this PR.
  • Tests will be added after some discussion and review.

Changelog?

  • This PR doesn't need to update Changelog.
  • Changelog will be updated after some proper review.
  • Changelog has been updated in my PR.

Target branch?

  • The target branch is dev branch.

One last thing


python expects options to be a signed 32bit integer
@xwings
Copy link
Member

xwings commented Dec 14, 2023

Thanks and welcome to Qiling Framework

@xwings xwings merged commit 687b02f into qilingframework:dev Dec 14, 2023
5 checks passed
@Ninja3047 Ninja3047 deleted the fix-wait-overflow branch December 14, 2023 12:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants