diff options
Diffstat (limited to 'drivers/usb/gadget/function/rndis.c')
| -rw-r--r-- | drivers/usb/gadget/function/rndis.c | 17 | 
1 files changed, 14 insertions, 3 deletions
| diff --git a/drivers/usb/gadget/function/rndis.c b/drivers/usb/gadget/function/rndis.c index 431d5a7d737e..00b3f6b3bb31 100644 --- a/drivers/usb/gadget/function/rndis.c +++ b/drivers/usb/gadget/function/rndis.c @@ -637,14 +637,17 @@ static int rndis_set_response(struct rndis_params *params,  	rndis_set_cmplt_type *resp;  	rndis_resp_t *r; +	BufLength = le32_to_cpu(buf->InformationBufferLength); +	BufOffset = le32_to_cpu(buf->InformationBufferOffset); +	if ((BufLength > RNDIS_MAX_TOTAL_SIZE) || +	    (BufOffset + 8 >= RNDIS_MAX_TOTAL_SIZE)) +		    return -EINVAL; +  	r = rndis_add_response(params, sizeof(rndis_set_cmplt_type));  	if (!r)  		return -ENOMEM;  	resp = (rndis_set_cmplt_type *)r->buf; -	BufLength = le32_to_cpu(buf->InformationBufferLength); -	BufOffset = le32_to_cpu(buf->InformationBufferOffset); -  #ifdef	VERBOSE_DEBUG  	pr_debug("%s: Length: %d\n", __func__, BufLength);  	pr_debug("%s: Offset: %d\n", __func__, BufOffset); @@ -919,6 +922,7 @@ struct rndis_params *rndis_register(void (*resp_avail)(void *v), void *v)  	params->resp_avail = resp_avail;  	params->v = v;  	INIT_LIST_HEAD(¶ms->resp_queue); +	spin_lock_init(¶ms->resp_lock);  	pr_debug("%s: configNr = %d\n", __func__, i);  	return params; @@ -1012,12 +1016,14 @@ void rndis_free_response(struct rndis_params *params, u8 *buf)  {  	rndis_resp_t *r, *n; +	spin_lock(¶ms->resp_lock);  	list_for_each_entry_safe(r, n, ¶ms->resp_queue, list) {  		if (r->buf == buf) {  			list_del(&r->list);  			kfree(r);  		}  	} +	spin_unlock(¶ms->resp_lock);  }  EXPORT_SYMBOL_GPL(rndis_free_response); @@ -1027,14 +1033,17 @@ u8 *rndis_get_next_response(struct rndis_params *params, u32 *length)  	if (!length) return NULL; +	spin_lock(¶ms->resp_lock);  	list_for_each_entry_safe(r, n, ¶ms->resp_queue, list) {  		if (!r->send) {  			r->send = 1;  			*length = r->length; +			spin_unlock(¶ms->resp_lock);  			return r->buf;  		}  	} +	spin_unlock(¶ms->resp_lock);  	return NULL;  }  EXPORT_SYMBOL_GPL(rndis_get_next_response); @@ -1051,7 +1060,9 @@ static rndis_resp_t *rndis_add_response(struct rndis_params *params, u32 length)  	r->length = length;  	r->send = 0; +	spin_lock(¶ms->resp_lock);  	list_add_tail(&r->list, ¶ms->resp_queue); +	spin_unlock(¶ms->resp_lock);  	return r;  } |