mirror of
				https://github.com/torvalds/linux.git
				synced 2025-10-31 16:48:26 +02:00 
			
		
		
		
	padata: Convert from atomic_t to refcount_t on parallel_data->refcnt
refcount_t type and corresponding API can protect refcounters from accidental underflow and overflow and further use-after-free situations. Signed-off-by: Xiyu Yang <xiyuyang19@fudan.edu.cn> Signed-off-by: Xin Tan <tanxin.ctf@gmail.com> Acked-by: Daniel Jordan <daniel.m.jordan@oracle.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
This commit is contained in:
		
							parent
							
								
									192b722f38
								
							
						
					
					
						commit
						d5ee8e750c
					
				
					 2 changed files with 6 additions and 5 deletions
				
			
		|  | @ -12,6 +12,7 @@ | ||||||
| #ifndef PADATA_H | #ifndef PADATA_H | ||||||
| #define PADATA_H | #define PADATA_H | ||||||
| 
 | 
 | ||||||
|  | #include <linux/refcount.h> | ||||||
| #include <linux/compiler_types.h> | #include <linux/compiler_types.h> | ||||||
| #include <linux/workqueue.h> | #include <linux/workqueue.h> | ||||||
| #include <linux/spinlock.h> | #include <linux/spinlock.h> | ||||||
|  | @ -96,7 +97,7 @@ struct parallel_data { | ||||||
| 	struct padata_shell		*ps; | 	struct padata_shell		*ps; | ||||||
| 	struct padata_list		__percpu *reorder_list; | 	struct padata_list		__percpu *reorder_list; | ||||||
| 	struct padata_serial_queue	__percpu *squeue; | 	struct padata_serial_queue	__percpu *squeue; | ||||||
| 	atomic_t			refcnt; | 	refcount_t			refcnt; | ||||||
| 	unsigned int			seq_nr; | 	unsigned int			seq_nr; | ||||||
| 	unsigned int			processed; | 	unsigned int			processed; | ||||||
| 	int				cpu; | 	int				cpu; | ||||||
|  |  | ||||||
|  | @ -211,7 +211,7 @@ int padata_do_parallel(struct padata_shell *ps, | ||||||
| 	if ((pinst->flags & PADATA_RESET)) | 	if ((pinst->flags & PADATA_RESET)) | ||||||
| 		goto out; | 		goto out; | ||||||
| 
 | 
 | ||||||
| 	atomic_inc(&pd->refcnt); | 	refcount_inc(&pd->refcnt); | ||||||
| 	padata->pd = pd; | 	padata->pd = pd; | ||||||
| 	padata->cb_cpu = *cb_cpu; | 	padata->cb_cpu = *cb_cpu; | ||||||
| 
 | 
 | ||||||
|  | @ -383,7 +383,7 @@ static void padata_serial_worker(struct work_struct *serial_work) | ||||||
| 	} | 	} | ||||||
| 	local_bh_enable(); | 	local_bh_enable(); | ||||||
| 
 | 
 | ||||||
| 	if (atomic_sub_and_test(cnt, &pd->refcnt)) | 	if (refcount_sub_and_test(cnt, &pd->refcnt)) | ||||||
| 		padata_free_pd(pd); | 		padata_free_pd(pd); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -593,7 +593,7 @@ static struct parallel_data *padata_alloc_pd(struct padata_shell *ps) | ||||||
| 	padata_init_reorder_list(pd); | 	padata_init_reorder_list(pd); | ||||||
| 	padata_init_squeues(pd); | 	padata_init_squeues(pd); | ||||||
| 	pd->seq_nr = -1; | 	pd->seq_nr = -1; | ||||||
| 	atomic_set(&pd->refcnt, 1); | 	refcount_set(&pd->refcnt, 1); | ||||||
| 	spin_lock_init(&pd->lock); | 	spin_lock_init(&pd->lock); | ||||||
| 	pd->cpu = cpumask_first(pd->cpumask.pcpu); | 	pd->cpu = cpumask_first(pd->cpumask.pcpu); | ||||||
| 	INIT_WORK(&pd->reorder_work, invoke_padata_reorder); | 	INIT_WORK(&pd->reorder_work, invoke_padata_reorder); | ||||||
|  | @ -667,7 +667,7 @@ static int padata_replace(struct padata_instance *pinst) | ||||||
| 	synchronize_rcu(); | 	synchronize_rcu(); | ||||||
| 
 | 
 | ||||||
| 	list_for_each_entry_continue_reverse(ps, &pinst->pslist, list) | 	list_for_each_entry_continue_reverse(ps, &pinst->pslist, list) | ||||||
| 		if (atomic_dec_and_test(&ps->opd->refcnt)) | 		if (refcount_dec_and_test(&ps->opd->refcnt)) | ||||||
| 			padata_free_pd(ps->opd); | 			padata_free_pd(ps->opd); | ||||||
| 
 | 
 | ||||||
| 	pinst->flags &= ~PADATA_RESET; | 	pinst->flags &= ~PADATA_RESET; | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue
	
	 Xiyu Yang
						Xiyu Yang