mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-10 22:40:54 -04:00
qcacld-3.0: Check buff len alloc in __iw_set_packet_filter_params
In __iw_set_packet_filter_params(), a user controlled length value, priv_data.length, is used to allocated a buffer. This buffer is then cast to a struct pointer of struct pkt_filter_cfg type without ensuring the buffer is of proper length. Add a sanity check on priv_data.length to ensure that the command being issued has proper parameters. Change-Id: Ia871e35ef938ca889fb6b1609a0c881d76f29e4b CRs-Fixed: 2250775
This commit is contained in:
parent
577f1450a8
commit
69d0780f6e
1 changed files with 40 additions and 2 deletions
|
|
@ -8061,6 +8061,38 @@ static int iw_set_keepalive_params(struct net_device *dev,
|
|||
}
|
||||
|
||||
#ifdef WLAN_FEATURE_PACKET_FILTERING
|
||||
/**
|
||||
* validate_packet_filter_params_size() - Validate the size of the params rcvd
|
||||
* @priv_data: Pointer to the priv data from user space
|
||||
* @request: Pointer to the struct containing the copied data from user space
|
||||
*
|
||||
* Return: False on invalid length, true otherwise
|
||||
*/
|
||||
static bool validate_packet_filter_params_size(struct pkt_filter_cfg *request,
|
||||
uint16_t length)
|
||||
{
|
||||
int max_params_size, rcvd_params_size;
|
||||
|
||||
max_params_size = HDD_MAX_CMP_PER_PACKET_FILTER *
|
||||
sizeof(struct pkt_filter_param_cfg);
|
||||
|
||||
if (length < sizeof(struct pkt_filter_cfg) - max_params_size) {
|
||||
hdd_err("Less than minimum number of arguments needed");
|
||||
return false;
|
||||
}
|
||||
|
||||
rcvd_params_size = request->num_params *
|
||||
sizeof(struct pkt_filter_param_cfg);
|
||||
|
||||
if (length != sizeof(struct pkt_filter_cfg) -
|
||||
max_params_size + rcvd_params_size) {
|
||||
hdd_err("Arguments do not match the number of params provided");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* __iw_set_packet_filter_params() - set packet filter parameters in target
|
||||
* @dev: Pointer to netdev
|
||||
|
|
@ -8101,8 +8133,7 @@ static int __iw_set_packet_filter_params(struct net_device *dev,
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
if ((NULL == priv_data.pointer) || (0 == priv_data.length) ||
|
||||
priv_data.length < sizeof(struct pkt_filter_cfg)) {
|
||||
if ((NULL == priv_data.pointer) || (0 == priv_data.length)) {
|
||||
hdd_err("invalid priv data %pK or invalid priv data length %d",
|
||||
priv_data.pointer, priv_data.length);
|
||||
return -EINVAL;
|
||||
|
|
@ -8122,11 +8153,18 @@ static int __iw_set_packet_filter_params(struct net_device *dev,
|
|||
/* copy data using copy_from_user */
|
||||
request = mem_alloc_copy_from_user_helper(priv_data.pointer,
|
||||
priv_data.length);
|
||||
|
||||
if (NULL == request) {
|
||||
hdd_err("mem_alloc_copy_from_user_helper fail");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
if (!validate_packet_filter_params_size(request, priv_data.length)) {
|
||||
hdd_err("Invalid priv data length %d", priv_data.length);
|
||||
qdf_mem_free(request);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (request->filter_action == HDD_RCV_FILTER_SET)
|
||||
hdd_ctx->user_configured_pkt_filter_rules |=
|
||||
1 << request->filter_id;
|
||||
|
|
|
|||
Loading…
Reference in a new issue