mirror of
				https://github.com/python/cpython.git
				synced 2025-11-04 11:49:12 +00:00 
			
		
		
		
	gh-126138: Fix use-after-free in _asyncio.Task by evil __getattribute__ (#126305)
				
					
				
			Co-authored-by: Carol Willing <carolcode@willingconsulting.com>
This commit is contained in:
		
							parent
							
								
									914356f4d4
								
							
						
					
					
						commit
						f032f6ba8f
					
				
					 2 changed files with 23 additions and 2 deletions
				
			
		| 
						 | 
				
			
			@ -0,0 +1,3 @@
 | 
			
		|||
Fix a use-after-free crash on :class:`asyncio.Task` objects
 | 
			
		||||
whose underlying coroutine yields an object that implements
 | 
			
		||||
an evil :meth:`~object.__getattribute__`. Patch by Nico Posada.
 | 
			
		||||
| 
						 | 
				
			
			@ -2967,8 +2967,17 @@ task_step_handle_result_impl(asyncio_state *state, TaskObj *task, PyObject *resu
 | 
			
		|||
        if (task->task_must_cancel) {
 | 
			
		||||
            PyObject *r;
 | 
			
		||||
            int is_true;
 | 
			
		||||
 | 
			
		||||
            // Beware: An evil `__getattribute__` could
 | 
			
		||||
            // prematurely delete task->task_cancel_msg before the
 | 
			
		||||
            // task is cancelled, thereby causing a UAF crash.
 | 
			
		||||
            //
 | 
			
		||||
            // See https://github.com/python/cpython/issues/126138
 | 
			
		||||
            PyObject *task_cancel_msg = Py_NewRef(task->task_cancel_msg);
 | 
			
		||||
            r = PyObject_CallMethodOneArg(result, &_Py_ID(cancel),
 | 
			
		||||
                                             task->task_cancel_msg);
 | 
			
		||||
                                          task_cancel_msg);
 | 
			
		||||
            Py_DECREF(task_cancel_msg);
 | 
			
		||||
 | 
			
		||||
            if (r == NULL) {
 | 
			
		||||
                return NULL;
 | 
			
		||||
            }
 | 
			
		||||
| 
						 | 
				
			
			@ -3060,8 +3069,17 @@ task_step_handle_result_impl(asyncio_state *state, TaskObj *task, PyObject *resu
 | 
			
		|||
        if (task->task_must_cancel) {
 | 
			
		||||
            PyObject *r;
 | 
			
		||||
            int is_true;
 | 
			
		||||
 | 
			
		||||
            // Beware: An evil `__getattribute__` could
 | 
			
		||||
            // prematurely delete task->task_cancel_msg before the
 | 
			
		||||
            // task is cancelled, thereby causing a UAF crash.
 | 
			
		||||
            //
 | 
			
		||||
            // See https://github.com/python/cpython/issues/126138
 | 
			
		||||
            PyObject *task_cancel_msg = Py_NewRef(task->task_cancel_msg);
 | 
			
		||||
            r = PyObject_CallMethodOneArg(result, &_Py_ID(cancel),
 | 
			
		||||
                                             task->task_cancel_msg);
 | 
			
		||||
                                          task_cancel_msg);
 | 
			
		||||
            Py_DECREF(task_cancel_msg);
 | 
			
		||||
 | 
			
		||||
            if (r == NULL) {
 | 
			
		||||
                return NULL;
 | 
			
		||||
            }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue