Fix crash caused by invalid memory write when recording audio
In some scenarios memcpy can write to 8 bytes (or more?) over the buffer end. Thanks to Guilherme for reporting the issue and testing the fix.
This commit is contained in:
		
							parent
							
								
									92f4b1a6f1
								
							
						
					
					
						commit
						88d06478d3
					
				| @ -191,18 +191,7 @@ static int pa_sound_device_read(pa_handle *p) { | |||||||
|         if((clock_get_monotonic_seconds() - start_time) * 1000 >= timeout_ms) |         if((clock_get_monotonic_seconds() - start_time) * 1000 >= timeout_ms) | ||||||
|             return -1; |             return -1; | ||||||
| 
 | 
 | ||||||
|         if(p->read_data) { |         if(!p->read_data) { | ||||||
|             assert(p->output_index == 0); |  | ||||||
|             memcpy(p->output_data, (const uint8_t*)p->read_data + p->read_index, p->read_length); |  | ||||||
|             p->output_index += p->read_length; |  | ||||||
|             p->read_data = NULL; |  | ||||||
|             p->read_length = 0; |  | ||||||
|             p->read_index = 0; |  | ||||||
| 
 |  | ||||||
|             if(pa_stream_drop(p->stream) != 0) |  | ||||||
|                 goto fail; |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|             pa_mainloop_prepare(p->mainloop, 1 * 1000); // 1 ms
 |             pa_mainloop_prepare(p->mainloop, 1 * 1000); // 1 ms
 | ||||||
|             pa_mainloop_poll(p->mainloop); |             pa_mainloop_poll(p->mainloop); | ||||||
|             pa_mainloop_dispatch(p->mainloop); |             pa_mainloop_dispatch(p->mainloop); | ||||||
| @ -221,21 +210,24 @@ static int pa_sound_device_read(pa_handle *p) { | |||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             if(p->read_length <= 0) { |             if(p->read_length <= 0) { | ||||||
|  |                 p->read_data = NULL; | ||||||
|  |                 if(pa_stream_drop(p->stream) != 0) | ||||||
|  |                     goto fail; | ||||||
|  | 
 | ||||||
|                 CHECK_DEAD_GOTO(p, rerror, fail); |                 CHECK_DEAD_GOTO(p, rerror, fail); | ||||||
|                 continue; |                 continue; | ||||||
|             } |             } | ||||||
|  |         } | ||||||
| 
 | 
 | ||||||
|         const size_t space_free_in_output_buffer = p->output_length - p->output_index; |         const size_t space_free_in_output_buffer = p->output_length - p->output_index; | ||||||
|         if(space_free_in_output_buffer < p->read_length) { |         if(space_free_in_output_buffer < p->read_length) { | ||||||
|             assert(p->read_index == 0); |             memcpy(p->output_data + p->output_index, (const uint8_t*)p->read_data + p->read_index, space_free_in_output_buffer); | ||||||
|             memcpy(p->output_data + p->output_index, p->read_data, space_free_in_output_buffer); |  | ||||||
|             p->output_index = 0; |             p->output_index = 0; | ||||||
|             p->read_index += space_free_in_output_buffer; |             p->read_index += space_free_in_output_buffer; | ||||||
|             p->read_length -= space_free_in_output_buffer; |             p->read_length -= space_free_in_output_buffer; | ||||||
|             break; |             break; | ||||||
|         } else { |         } else { | ||||||
|             assert(p->read_index == 0); |             memcpy(p->output_data + p->output_index, (const uint8_t*)p->read_data + p->read_index, p->read_length); | ||||||
|             memcpy(p->output_data + p->output_index, p->read_data, p->read_length); |  | ||||||
|             p->output_index += p->read_length; |             p->output_index += p->read_length; | ||||||
|             p->read_data = NULL; |             p->read_data = NULL; | ||||||
|             p->read_length = 0; |             p->read_length = 0; | ||||||
| @ -359,12 +351,12 @@ std::vector<AudioInput> get_pulseaudio_inputs() { | |||||||
|                 pa_operation_unref(pa_op); |                 pa_operation_unref(pa_op); | ||||||
|             pa_context_disconnect(ctx); |             pa_context_disconnect(ctx); | ||||||
|             pa_context_unref(ctx); |             pa_context_unref(ctx); | ||||||
|             pa_mainloop_free(main_loop); |             break; | ||||||
|             return inputs; |  | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         pa_mainloop_iterate(main_loop, 1, NULL); |         pa_mainloop_iterate(main_loop, 1, NULL); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     pa_mainloop_free(main_loop); |     pa_mainloop_free(main_loop); | ||||||
|  |     return inputs; | ||||||
| } | } | ||||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 dec05eba
						dec05eba