mirror of
				https://github.com/torvalds/linux.git
				synced 2025-10-31 08:38:45 +02:00 
			
		
		
		
	cachefiles: add consistency check for copen/cread
This prevents malicious processes from completing random copen/cread
requests and crashing the system. Added checks are listed below:
  * Generic, copen can only complete open requests, and cread can only
    complete read requests.
  * For copen, ondemand_id must not be 0, because this indicates that the
    request has not been read by the daemon.
  * For cread, the object corresponding to fd and req should be the same.
Signed-off-by: Baokun Li <libaokun1@huawei.com>
Link: https://lore.kernel.org/r/20240522114308.2402121-7-libaokun@huaweicloud.com
Acked-by: Jeff Layton <jlayton@kernel.org>
Reviewed-by: Jingbo Xu <jefflexu@linux.alibaba.com>
Signed-off-by: Christian Brauner <brauner@kernel.org>
			
			
This commit is contained in:
		
							parent
							
								
									3e6d704f02
								
							
						
					
					
						commit
						a26dc49df3
					
				
					 1 changed files with 20 additions and 7 deletions
				
			
		|  | @ -82,12 +82,12 @@ static loff_t cachefiles_ondemand_fd_llseek(struct file *filp, loff_t pos, | |||
| } | ||||
| 
 | ||||
| static long cachefiles_ondemand_fd_ioctl(struct file *filp, unsigned int ioctl, | ||||
| 					 unsigned long arg) | ||||
| 					 unsigned long id) | ||||
| { | ||||
| 	struct cachefiles_object *object = filp->private_data; | ||||
| 	struct cachefiles_cache *cache = object->volume->cache; | ||||
| 	struct cachefiles_req *req; | ||||
| 	unsigned long id; | ||||
| 	XA_STATE(xas, &cache->reqs, id); | ||||
| 
 | ||||
| 	if (ioctl != CACHEFILES_IOC_READ_COMPLETE) | ||||
| 		return -EINVAL; | ||||
|  | @ -95,10 +95,15 @@ static long cachefiles_ondemand_fd_ioctl(struct file *filp, unsigned int ioctl, | |||
| 	if (!test_bit(CACHEFILES_ONDEMAND_MODE, &cache->flags)) | ||||
| 		return -EOPNOTSUPP; | ||||
| 
 | ||||
| 	id = arg; | ||||
| 	req = xa_erase(&cache->reqs, id); | ||||
| 	if (!req) | ||||
| 	xa_lock(&cache->reqs); | ||||
| 	req = xas_load(&xas); | ||||
| 	if (!req || req->msg.opcode != CACHEFILES_OP_READ || | ||||
| 	    req->object != object) { | ||||
| 		xa_unlock(&cache->reqs); | ||||
| 		return -EINVAL; | ||||
| 	} | ||||
| 	xas_store(&xas, NULL); | ||||
| 	xa_unlock(&cache->reqs); | ||||
| 
 | ||||
| 	trace_cachefiles_ondemand_cread(object, id); | ||||
| 	complete(&req->done); | ||||
|  | @ -126,6 +131,7 @@ int cachefiles_ondemand_copen(struct cachefiles_cache *cache, char *args) | |||
| 	unsigned long id; | ||||
| 	long size; | ||||
| 	int ret; | ||||
| 	XA_STATE(xas, &cache->reqs, 0); | ||||
| 
 | ||||
| 	if (!test_bit(CACHEFILES_ONDEMAND_MODE, &cache->flags)) | ||||
| 		return -EOPNOTSUPP; | ||||
|  | @ -149,9 +155,16 @@ int cachefiles_ondemand_copen(struct cachefiles_cache *cache, char *args) | |||
| 	if (ret) | ||||
| 		return ret; | ||||
| 
 | ||||
| 	req = xa_erase(&cache->reqs, id); | ||||
| 	if (!req) | ||||
| 	xa_lock(&cache->reqs); | ||||
| 	xas.xa_index = id; | ||||
| 	req = xas_load(&xas); | ||||
| 	if (!req || req->msg.opcode != CACHEFILES_OP_OPEN || | ||||
| 	    !req->object->ondemand->ondemand_id) { | ||||
| 		xa_unlock(&cache->reqs); | ||||
| 		return -EINVAL; | ||||
| 	} | ||||
| 	xas_store(&xas, NULL); | ||||
| 	xa_unlock(&cache->reqs); | ||||
| 
 | ||||
| 	/* fail OPEN request if copen format is invalid */ | ||||
| 	ret = kstrtol(psize, 0, &size); | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue
	
	 Baokun Li
						Baokun Li