forked from mirrors/linux
		
	scatterlist: prevent invalid free when alloc fails
When alloc fails, free_table is being called. Depending on the number of bytes requested, we determine if we are going to call _get_free_page() or kmalloc(). When alloc fails, our math is wrong (due to sg_size - 1), and the last buffer is wrongfully assumed to have been allocated by kmalloc. Hence, kfree gets called and a panic occurs. Signed-off-by: Jeffrey Carlyle <jeff.carlyle@motorola.com> Signed-off-by: Olusanya Soyannwo <c23746@motorola.com> Acked-by: Tejun Heo <tj@kernel.org> Signed-off-by: Jens Axboe <jaxboe@fusionio.com>
This commit is contained in:
		
							parent
							
								
									b76b4014f9
								
							
						
					
					
						commit
						edce6820a9
					
				
					 1 changed files with 12 additions and 2 deletions
				
			
		| 
						 | 
					@ -248,8 +248,18 @@ int __sg_alloc_table(struct sg_table *table, unsigned int nents,
 | 
				
			||||||
		left -= sg_size;
 | 
							left -= sg_size;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		sg = alloc_fn(alloc_size, gfp_mask);
 | 
							sg = alloc_fn(alloc_size, gfp_mask);
 | 
				
			||||||
		if (unlikely(!sg))
 | 
							if (unlikely(!sg)) {
 | 
				
			||||||
			return -ENOMEM;
 | 
								/*
 | 
				
			||||||
 | 
								 * Adjust entry count to reflect that the last
 | 
				
			||||||
 | 
								 * entry of the previous table won't be used for
 | 
				
			||||||
 | 
								 * linkage.  Without this, sg_kfree() may get
 | 
				
			||||||
 | 
								 * confused.
 | 
				
			||||||
 | 
								 */
 | 
				
			||||||
 | 
								if (prv)
 | 
				
			||||||
 | 
									table->nents = ++table->orig_nents;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 			return -ENOMEM;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		sg_init_table(sg, alloc_size);
 | 
							sg_init_table(sg, alloc_size);
 | 
				
			||||||
		table->nents = table->orig_nents += sg_size;
 | 
							table->nents = table->orig_nents += sg_size;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue