ceph: fix bounds check in ceph_decode_need and ceph_encode_need
Given a large n, the bounds check (*p + n > end) can be bypassed due to pointer wraparound. A safer check is (n > end - *p). [elder@dreamhost.com: inverted test and renamed ceph_has_room()] Signed-off-by: Xi Wang <xi.wang@gmail.com> Reviewed-by: Alex Elder <elder@dreamhost.com>
This commit is contained in:
		
					parent
					
						
							
								065a68f916
							
						
					
				
			
			
				commit
				
					
						76aa542fb9
					
				
			
		
					 1 changed files with 7 additions and 2 deletions
				
			
		|  | @ -45,9 +45,14 @@ static inline void ceph_decode_copy(void **p, void *pv, size_t n) | ||||||
| /*
 | /*
 | ||||||
|  * bounds check input. |  * bounds check input. | ||||||
|  */ |  */ | ||||||
|  | static inline int ceph_has_room(void **p, void *end, size_t n) | ||||||
|  | { | ||||||
|  | 	return end >= *p && n <= end - *p; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| #define ceph_decode_need(p, end, n, bad)		\ | #define ceph_decode_need(p, end, n, bad)		\ | ||||||
| 	do {						\ | 	do {						\ | ||||||
| 		if (unlikely(*(p) + (n) > (end))) 	\ | 		if (!likely(ceph_has_room(p, end, n)))	\ | ||||||
| 			goto bad;			\ | 			goto bad;			\ | ||||||
| 	} while (0) | 	} while (0) | ||||||
| 
 | 
 | ||||||
|  | @ -166,7 +171,7 @@ static inline void ceph_encode_string(void **p, void *end, | ||||||
| 
 | 
 | ||||||
| #define ceph_encode_need(p, end, n, bad)		\ | #define ceph_encode_need(p, end, n, bad)		\ | ||||||
| 	do {						\ | 	do {						\ | ||||||
| 		if (unlikely(*(p) + (n) > (end))) 	\ | 		if (!likely(ceph_has_room(p, end, n)))	\ | ||||||
| 			goto bad;			\ | 			goto bad;			\ | ||||||
| 	} while (0) | 	} while (0) | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Xi Wang
				Xi Wang