mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-01 00:58:39 +02:00 
			
		
		
		
	tracing: Prevent deleting instances when they are being read
Add a ref count to the trace_array structure and prevent removal of instances that have open descriptors. Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
This commit is contained in:
		
							parent
							
								
									121aaee7b0
								
							
						
					
					
						commit
						a695cb5816
					
				
					 2 changed files with 24 additions and 0 deletions
				
			
		|  | @ -2613,6 +2613,8 @@ __tracing_open(struct inode *inode, struct file *file, bool snapshot) | ||||||
| 		tracing_iter_reset(iter, cpu); | 		tracing_iter_reset(iter, cpu); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | 	tr->ref++; | ||||||
|  | 
 | ||||||
| 	mutex_unlock(&trace_types_lock); | 	mutex_unlock(&trace_types_lock); | ||||||
| 
 | 
 | ||||||
| 	return iter; | 	return iter; | ||||||
|  | @ -2649,6 +2651,10 @@ static int tracing_release(struct inode *inode, struct file *file) | ||||||
| 	tr = iter->tr; | 	tr = iter->tr; | ||||||
| 
 | 
 | ||||||
| 	mutex_lock(&trace_types_lock); | 	mutex_lock(&trace_types_lock); | ||||||
|  | 
 | ||||||
|  | 	WARN_ON(!tr->ref); | ||||||
|  | 	tr->ref--; | ||||||
|  | 
 | ||||||
| 	for_each_tracing_cpu(cpu) { | 	for_each_tracing_cpu(cpu) { | ||||||
| 		if (iter->buffer_iter[cpu]) | 		if (iter->buffer_iter[cpu]) | ||||||
| 			ring_buffer_read_finish(iter->buffer_iter[cpu]); | 			ring_buffer_read_finish(iter->buffer_iter[cpu]); | ||||||
|  | @ -4460,6 +4466,10 @@ static int tracing_buffers_open(struct inode *inode, struct file *filp) | ||||||
| 	if (!info) | 	if (!info) | ||||||
| 		return -ENOMEM; | 		return -ENOMEM; | ||||||
| 
 | 
 | ||||||
|  | 	mutex_lock(&trace_types_lock); | ||||||
|  | 
 | ||||||
|  | 	tr->ref++; | ||||||
|  | 
 | ||||||
| 	info->iter.tr		= tr; | 	info->iter.tr		= tr; | ||||||
| 	info->iter.cpu_file	= tc->cpu; | 	info->iter.cpu_file	= tc->cpu; | ||||||
| 	info->iter.trace	= tr->current_trace; | 	info->iter.trace	= tr->current_trace; | ||||||
|  | @ -4470,6 +4480,8 @@ static int tracing_buffers_open(struct inode *inode, struct file *filp) | ||||||
| 
 | 
 | ||||||
| 	filp->private_data = info; | 	filp->private_data = info; | ||||||
| 
 | 
 | ||||||
|  | 	mutex_unlock(&trace_types_lock); | ||||||
|  | 
 | ||||||
| 	return nonseekable_open(inode, filp); | 	return nonseekable_open(inode, filp); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -4568,10 +4580,17 @@ static int tracing_buffers_release(struct inode *inode, struct file *file) | ||||||
| 	struct ftrace_buffer_info *info = file->private_data; | 	struct ftrace_buffer_info *info = file->private_data; | ||||||
| 	struct trace_iterator *iter = &info->iter; | 	struct trace_iterator *iter = &info->iter; | ||||||
| 
 | 
 | ||||||
|  | 	mutex_lock(&trace_types_lock); | ||||||
|  | 
 | ||||||
|  | 	WARN_ON(!iter->tr->ref); | ||||||
|  | 	iter->tr->ref--; | ||||||
|  | 
 | ||||||
| 	if (info->spare) | 	if (info->spare) | ||||||
| 		ring_buffer_free_read_page(iter->trace_buffer->buffer, info->spare); | 		ring_buffer_free_read_page(iter->trace_buffer->buffer, info->spare); | ||||||
| 	kfree(info); | 	kfree(info); | ||||||
| 
 | 
 | ||||||
|  | 	mutex_unlock(&trace_types_lock); | ||||||
|  | 
 | ||||||
| 	return 0; | 	return 0; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -5411,6 +5430,10 @@ static int instance_delete(const char *name) | ||||||
| 	if (!found) | 	if (!found) | ||||||
| 		goto out_unlock; | 		goto out_unlock; | ||||||
| 
 | 
 | ||||||
|  | 	ret = -EBUSY; | ||||||
|  | 	if (tr->ref) | ||||||
|  | 		goto out_unlock; | ||||||
|  | 
 | ||||||
| 	list_del(&tr->list); | 	list_del(&tr->list); | ||||||
| 
 | 
 | ||||||
| 	event_trace_del_tracer(tr); | 	event_trace_del_tracer(tr); | ||||||
|  |  | ||||||
|  | @ -219,6 +219,7 @@ struct trace_array { | ||||||
| 	struct list_head	systems; | 	struct list_head	systems; | ||||||
| 	struct list_head	events; | 	struct list_head	events; | ||||||
| 	struct task_struct	*waiter; | 	struct task_struct	*waiter; | ||||||
|  | 	int			ref; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| enum { | enum { | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue
	
	 Steven Rostedt (Red Hat)
						Steven Rostedt (Red Hat)