diff options
author | Oleg Matcovschi <omatcovschi@google.com> | 2018-03-13 22:19:45 -0700 |
---|---|---|
committer | Siyuan Zhou <siyuanzhou@google.com> | 2018-03-14 17:34:13 +0000 |
commit | abd44345f20fe057feccf80096db9e0dc4df1624 (patch) | |
tree | 76a6fd1d3eb317669a3acdf26752f5635d1ed7bf | |
parent | 0b570a88eb70d67aed2112c40c4225b35a992dea (diff) | |
parent | 2642c1fd82af2396826d12dc0098021b55d15ac8 (diff) |
Merge android-msm-marlin-3.18-oc-mr1-security-next into android-msm-marlin-3.18-oc-mr1android-8.1.0_r0.44
April 2018.2
Bug: 73498666
Change-Id: Id6c61080eabaa3690c688a64c62f5ee685e3a73f
Signed-Off-By: Oleg Matcovschi <omatcovschi@google.com>
26 files changed, 295 insertions, 76 deletions
diff --git a/drivers/char/diag/diag_dci.c b/drivers/char/diag/diag_dci.c index b7c5e7ded6e3..5eb7839be4ac 100644 --- a/drivers/char/diag/diag_dci.c +++ b/drivers/char/diag/diag_dci.c @@ -1363,6 +1363,8 @@ void diag_dci_notify_client(int peripheral_mask, int data, int proc) struct siginfo info; struct list_head *start, *temp; struct diag_dci_client_tbl *entry = NULL; + struct pid *pid_struct = NULL; + struct task_struct *dci_task = NULL; memset(&info, 0, sizeof(struct siginfo)); info.si_code = SI_QUEUE; @@ -1380,20 +1382,32 @@ void diag_dci_notify_client(int peripheral_mask, int data, int proc) continue; if (entry->client_info.notification_list & peripheral_mask) { info.si_signo = entry->client_info.signal_type; - if (entry->client && - entry->tgid == entry->client->tgid) { - DIAG_LOG(DIAG_DEBUG_DCI, - "entry tgid = %d, dci client tgid = %d\n", - entry->tgid, entry->client->tgid); - stat = send_sig_info( - entry->client_info.signal_type, - &info, entry->client); - if (stat) - pr_err("diag: Err sending dci signal to client, signal data: 0x%x, stat: %d\n", + pid_struct = find_get_pid(entry->tgid); + if (pid_struct) { + dci_task = get_pid_task(pid_struct, + PIDTYPE_PID); + if (!dci_task) { + DIAG_LOG(DIAG_DEBUG_PERIPHERALS, + "diag: dci client with pid = %d Exited..\n", + entry->tgid); + mutex_unlock(&driver->dci_mutex); + return; + } + if (entry->client && + entry->tgid == dci_task->tgid) { + DIAG_LOG(DIAG_DEBUG_DCI, + "entry tgid = %d, dci client tgid = %d\n", + entry->tgid, dci_task->tgid); + stat = send_sig_info( + entry->client_info.signal_type, + &info, dci_task); + if (stat) + pr_err("diag: Err sending dci signal to client, signal data: 0x%x, stat: %d\n", info.si_int, stat); - } else - pr_err("diag: client data is corrupted, signal data: 0x%x, stat: %d\n", + } else + pr_err("diag: client data is corrupted, signal data: 0x%x, stat: %d\n", info.si_int, stat); + } } } mutex_unlock(&driver->dci_mutex); diff --git a/drivers/net/usb/cdc-phonet.c b/drivers/net/usb/cdc-phonet.c index 2ec1500d0077..63188bdfae9c 100644 --- a/drivers/net/usb/cdc-phonet.c +++ b/drivers/net/usb/cdc-phonet.c @@ -343,9 +343,9 @@ static int usbpn_probe(struct usb_interface *intf, const struct usb_device_id *i data = intf->altsetting->extra; len = intf->altsetting->extralen; - while (len >= 3) { + while (len > 0) { u8 dlen = data[0]; - if (dlen < 3) + if ((len < dlen) || (dlen < 3 )) return -EINVAL; /* bDescriptorType */ diff --git a/drivers/net/usb/cdc_ether.c b/drivers/net/usb/cdc_ether.c index d3920b54a92c..4544cb6bcf78 100644 --- a/drivers/net/usb/cdc_ether.c +++ b/drivers/net/usb/cdc_ether.c @@ -154,7 +154,13 @@ int usbnet_generic_cdc_bind(struct usbnet *dev, struct usb_interface *intf) memset(info, 0, sizeof(*info)); info->control = intf; - while (len > 3) { + while (len > 0) { + + if ((len < buf[0]) || (buf[0] < 3)) { + dev_dbg(&intf->dev, "invalid descriptor buffer length\n"); + goto bad_desc; + } + if (buf[1] != USB_DT_CS_INTERFACE) goto next_desc; diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c index b11f8eaba406..b4e543cd34c0 100644 --- a/drivers/net/usb/qmi_wwan.c +++ b/drivers/net/usb/qmi_wwan.c @@ -241,9 +241,14 @@ static int qmi_wwan_bind(struct usbnet *dev, struct usb_interface *intf) info->data = intf; /* and a number of CDC descriptors */ - while (len > 3) { + while (len > 0) { struct usb_descriptor_header *h = (void *)buf; + if ((len < buf[0]) || (buf[0] < 3)) { + dev_dbg(&intf->dev, "invalid descriptor buffer length\n"); + goto err; + } + /* ignore any misplaced descriptors */ if (h->bDescriptorType != USB_DT_CS_INTERFACE) goto next_desc; diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c index 66ba1ee09a6c..318707870cb2 100644 --- a/drivers/pci/pci-sysfs.c +++ b/drivers/pci/pci-sysfs.c @@ -513,7 +513,7 @@ static ssize_t driver_override_store(struct device *dev, const char *buf, size_t count) { struct pci_dev *pdev = to_pci_dev(dev); - char *driver_override, *old = pdev->driver_override, *cp; + char *driver_override, *old, *cp; /* We need to keep extra room for a newline */ if (count >= (PAGE_SIZE - 1)) @@ -527,12 +527,15 @@ static ssize_t driver_override_store(struct device *dev, if (cp) *cp = '\0'; + device_lock(dev); + old = pdev->driver_override; if (strlen(driver_override)) { pdev->driver_override = driver_override; } else { kfree(driver_override); pdev->driver_override = NULL; } + device_unlock(dev); kfree(old); @@ -543,8 +546,12 @@ static ssize_t driver_override_show(struct device *dev, struct device_attribute *attr, char *buf) { struct pci_dev *pdev = to_pci_dev(dev); + ssize_t len; - return snprintf(buf, PAGE_SIZE, "%s\n", pdev->driver_override); + device_lock(dev); + len = snprintf(buf, PAGE_SIZE, "%s\n", pdev->driver_override); + device_unlock(dev); + return len; } static DEVICE_ATTR_RW(driver_override); diff --git a/drivers/platform/msm/ipa/ipa_v2/ipa_hdr.c b/drivers/platform/msm/ipa/ipa_v2/ipa_hdr.c index 9fde93371157..c8d4cd9c42f3 100644 --- a/drivers/platform/msm/ipa/ipa_v2/ipa_hdr.c +++ b/drivers/platform/msm/ipa/ipa_v2/ipa_hdr.c @@ -889,8 +889,17 @@ int __ipa_del_hdr(u32 hdr_hdl, bool by_user) return -EINVAL; } - if (by_user) + if (by_user) { + if (!strcmp(entry->name, IPA_LAN_RX_HDR_NAME)) { + IPADBG("Trying to delete hdr %s offset=%u\n", + entry->name, entry->offset_entry->offset); + if (!entry->offset_entry->offset) { + IPAERR("User cannot delete default header\n"); + return -EPERM; + } + } entry->user_deleted = true; + } if (--entry->ref_cnt) { IPADBG("hdr_hdl %x ref_cnt %d\n", hdr_hdl, entry->ref_cnt); @@ -1212,8 +1221,20 @@ int ipa2_reset_hdr(void) &ipa_ctx->hdr_tbl.head_hdr_entry_list, link) { /* do not remove the default header */ - if (!strcmp(entry->name, IPA_LAN_RX_HDR_NAME)) - continue; + if (!strcmp(entry->name, IPA_LAN_RX_HDR_NAME)) { + IPADBG("Trying to remove hdr %s offset=%u\n", + entry->name, entry->offset_entry->offset); + if (!entry->offset_entry->offset) { + if (entry->is_hdr_proc_ctx) { + mutex_unlock(&ipa_ctx->lock); + WARN_ON(1); + IPAERR("default header is proc ctx\n"); + return -EFAULT; + } + IPADBG("skip default header\n"); + continue; + } + } if (ipa_id_find(entry->id) == NULL) { WARN_ON(1); diff --git a/drivers/platform/msm/ipa/ipa_v2/rmnet_ipa.c b/drivers/platform/msm/ipa/ipa_v2/rmnet_ipa.c index 05472681d1a2..84bd6e32bcfa 100644 --- a/drivers/platform/msm/ipa/ipa_v2/rmnet_ipa.c +++ b/drivers/platform/msm/ipa/ipa_v2/rmnet_ipa.c @@ -398,12 +398,15 @@ int copy_ul_filter_rule_to_ipa(struct ipa_install_fltr_rule_req_msg_v01 { int i, j; + /* prevent multi-threads accessing num_q6_rule */ + mutex_lock(&add_mux_channel_lock); if (rule_req->filter_spec_list_valid == true) { num_q6_rule = rule_req->filter_spec_list_len; IPAWANDBG("Received (%d) install_flt_req\n", num_q6_rule); } else { num_q6_rule = 0; IPAWANERR("got no UL rules from modem\n"); + mutex_unlock(&add_mux_channel_lock); return -EINVAL; } @@ -597,9 +600,11 @@ failure: num_q6_rule = 0; memset(ipa_qmi_ctx->q6_ul_filter_rule, 0, sizeof(ipa_qmi_ctx->q6_ul_filter_rule)); + mutex_unlock(&add_mux_channel_lock); return -EINVAL; success: + mutex_unlock(&add_mux_channel_lock); return 0; } @@ -1411,6 +1416,8 @@ static int ipa_wwan_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) mutex_unlock(&add_mux_channel_lock); return -EFAULT; } + extend_ioctl_data.u.rmnet_mux_val.vchannel_name + [IFNAMSIZ-1] = '\0'; IPAWANDBG("ADD_MUX_CHANNEL(%d, name: %s)\n", extend_ioctl_data.u.rmnet_mux_val.mux_id, extend_ioctl_data.u.rmnet_mux_val.vchannel_name); @@ -1497,9 +1504,12 @@ static int ipa_wwan_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) /* already got Q6 UL filter rules*/ if (ipa_qmi_ctx && ipa_qmi_ctx->modem_cfg_emb_pipe_flt - == false) + == false) { + /* protect num_q6_rule */ + mutex_lock(&add_mux_channel_lock); rc = wwan_add_ul_flt_rule_to_ipa(); - else + mutex_unlock(&add_mux_channel_lock); + } else rc = 0; egress_set = true; if (rc) diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_hdr.c b/drivers/platform/msm/ipa/ipa_v3/ipa_hdr.c index ce5c0d410bd9..db2114ccc1f6 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_hdr.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_hdr.c @@ -650,8 +650,17 @@ int __ipa3_del_hdr(u32 hdr_hdl, bool by_user) return -EINVAL; } - if (by_user) + if (by_user) { + if (!strcmp(entry->name, IPA_LAN_RX_HDR_NAME)) { + IPADBG("Trying to delete hdr %s offset=%u\n", + entry->name, entry->offset_entry->offset); + if (!entry->offset_entry->offset) { + IPAERR("User cannot delete default header\n"); + return -EPERM; + } + } entry->user_deleted = true; + } if (--entry->ref_cnt) { IPADBG("hdr_hdl %x ref_cnt %d\n", hdr_hdl, entry->ref_cnt); @@ -949,8 +958,20 @@ int ipa3_reset_hdr(void) &ipa3_ctx->hdr_tbl.head_hdr_entry_list, link) { /* do not remove the default header */ - if (!strcmp(entry->name, IPA_LAN_RX_HDR_NAME)) - continue; + if (!strcmp(entry->name, IPA_LAN_RX_HDR_NAME)) { + IPADBG("Trying to remove hdr %s offset=%u\n", + entry->name, entry->offset_entry->offset); + if (!entry->offset_entry->offset) { + if (entry->is_hdr_proc_ctx) { + IPAERR("default header is proc ctx\n"); + mutex_unlock(&ipa3_ctx->lock); + WARN_ON(1); + return -EFAULT; + } + IPADBG("skip default header\n"); + continue; + } + } if (ipa3_id_find(entry->id) == NULL) { WARN_ON(1); diff --git a/drivers/platform/msm/ipa/ipa_v3/rmnet_ipa.c b/drivers/platform/msm/ipa/ipa_v3/rmnet_ipa.c index b49e08c305db..a225826b5e7a 100644 --- a/drivers/platform/msm/ipa/ipa_v3/rmnet_ipa.c +++ b/drivers/platform/msm/ipa/ipa_v3/rmnet_ipa.c @@ -412,6 +412,8 @@ int ipa3_copy_ul_filter_rule_to_ipa(struct ipa_install_fltr_rule_req_msg_v01 { int i, j; + /* prevent multi-threads accessing rmnet_ipa3_ctx->num_q6_rules */ + mutex_lock(&rmnet_ipa3_ctx->add_mux_channel_lock); if (rule_req->filter_spec_ex_list_valid == true) { rmnet_ipa3_ctx->num_q6_rules = rule_req->filter_spec_ex_list_len; @@ -420,6 +422,8 @@ int ipa3_copy_ul_filter_rule_to_ipa(struct ipa_install_fltr_rule_req_msg_v01 } else { rmnet_ipa3_ctx->num_q6_rules = 0; IPAWANERR("got no UL rules from modem\n"); + mutex_unlock(&rmnet_ipa3_ctx-> + add_mux_channel_lock); return -EINVAL; } @@ -622,9 +626,13 @@ failure: rmnet_ipa3_ctx->num_q6_rules = 0; memset(ipa3_qmi_ctx->q6_ul_filter_rule, 0, sizeof(ipa3_qmi_ctx->q6_ul_filter_rule)); + mutex_unlock(&rmnet_ipa3_ctx-> + add_mux_channel_lock); return -EINVAL; success: + mutex_unlock(&rmnet_ipa3_ctx-> + add_mux_channel_lock); return 0; } @@ -1431,6 +1439,8 @@ static int ipa3_wwan_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) add_mux_channel_lock); return -EFAULT; } + extend_ioctl_data.u.rmnet_mux_val.vchannel_name + [IFNAMSIZ-1] = '\0'; IPAWANDBG("ADD_MUX_CHANNEL(%d, name: %s)\n", extend_ioctl_data.u.rmnet_mux_val.mux_id, extend_ioctl_data.u.rmnet_mux_val.vchannel_name); diff --git a/drivers/soc/qcom/qdsp6v2/apr.c b/drivers/soc/qcom/qdsp6v2/apr.c index bbe686f4bc42..28c9de0ec9ea 100644 --- a/drivers/soc/qcom/qdsp6v2/apr.c +++ b/drivers/soc/qcom/qdsp6v2/apr.c @@ -598,7 +598,8 @@ void apr_cb_func(void *buf, int len, void *priv) temp_port = ((data.dest_port >> 8) * 8) + (data.dest_port & 0xFF); pr_debug("port = %d t_port = %d\n", data.src_port, temp_port); - if (c_svc->port_cnt && c_svc->port_fn[temp_port]) + if (((temp_port >= 0) && (temp_port < APR_MAX_PORTS)) + && (c_svc->port_cnt && c_svc->port_fn[temp_port])) c_svc->port_fn[temp_port](&data, c_svc->port_priv[temp_port]); else if (c_svc->fn) c_svc->fn(&data, c_svc->priv); diff --git a/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/HTT/htt_t2h.c b/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/HTT/htt_t2h.c index aa8c43cafa42..e09636ad49fb 100644 --- a/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/HTT/htt_t2h.c +++ b/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/HTT/htt_t2h.c @@ -172,7 +172,7 @@ htt_t2h_lp_msg_handler(void *context, adf_nbuf_t htt_t2h_msg ) { u_int16_t peer_id; u_int8_t tid; - int seq_num_start, seq_num_end; + u_int16_t seq_num_start, seq_num_end; enum htt_rx_flush_action action; peer_id = HTT_RX_FLUSH_PEER_ID_GET(*msg_word); @@ -264,6 +264,14 @@ htt_t2h_lp_msg_handler(void *context, adf_nbuf_t htt_t2h_msg ) peer_mac_addr = htt_t2h_mac_addr_deswizzle( (u_int8_t *) (msg_word+1), &mac_addr_deswizzle_buf[0]); + if (peer_id > ol_cfg_max_peer_id(pdev->ctrl_pdev)) { + adf_os_print("%s: HTT_T2H_MSG_TYPE_PEER_MAP," + "invalid peer_id, %u\n", + __FUNCTION__, + peer_id); + break; + } + ol_rx_peer_map_handler( pdev->txrx_pdev, peer_id, vdev_id, peer_mac_addr, 1/*can tx*/); break; @@ -273,6 +281,14 @@ htt_t2h_lp_msg_handler(void *context, adf_nbuf_t htt_t2h_msg ) u_int16_t peer_id; peer_id = HTT_RX_PEER_UNMAP_PEER_ID_GET(*msg_word); + if (peer_id > ol_cfg_max_peer_id(pdev->ctrl_pdev)) { + adf_os_print("%s: HTT_T2H_MSG_TYPE_PEER_UNMAP," + "invalid peer_id, %u\n", + __FUNCTION__, + peer_id); + break; + } + ol_rx_peer_unmap_handler(pdev->txrx_pdev, peer_id); break; } @@ -642,7 +658,7 @@ if (adf_os_unlikely(pdev->rx_ring.rx_reset)) { { u_int16_t peer_id; u_int8_t tid, pn_ie_cnt, *pn_ie=NULL; - int seq_num_start, seq_num_end; + u_int16_t seq_num_start, seq_num_end; /*First dword */ peer_id = HTT_RX_PN_IND_PEER_ID_GET(*msg_word); @@ -1044,8 +1060,8 @@ void htt_rx_frag_ind_flush_seq_num_range( htt_pdev_handle pdev, adf_nbuf_t rx_frag_ind_msg, - int *seq_num_start, - int *seq_num_end) + u_int16_t *seq_num_start, + u_int16_t *seq_num_end) { u_int32_t *msg_word; diff --git a/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/TXRX/ol_rx_defrag.c b/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/TXRX/ol_rx_defrag.c index cdbcc7667d07..5d6f2fd900e7 100644 --- a/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/TXRX/ol_rx_defrag.c +++ b/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/TXRX/ol_rx_defrag.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2014 The Linux Foundation. All rights reserved. + * Copyright (c) 2011-2014, 2016-2017 The Linux Foundation. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -195,12 +195,20 @@ ol_rx_frag_indication_handler( u_int8_t tid) { u_int16_t seq_num; - int seq_num_start, seq_num_end; + u_int16_t seq_num_start, seq_num_end; struct ol_txrx_peer_t *peer; htt_pdev_handle htt_pdev; adf_nbuf_t head_msdu, tail_msdu; void *rx_mpdu_desc; + if (tid >= OL_TXRX_NUM_EXT_TIDS) { + TXRX_PRINT(TXRX_PRINT_LEVEL_ERR, + "%s: invalid tid, %u\n", + __FUNCTION__, + tid); + return; + } + htt_pdev = pdev->htt_pdev; peer = ol_txrx_peer_find_by_id(pdev, peer_id); @@ -248,7 +256,7 @@ ol_rx_reorder_flush_frag( htt_pdev_handle htt_pdev, struct ol_txrx_peer_t *peer, unsigned tid, - int seq_num) + u_int16_t seq_num) { struct ol_rx_reorder_array_elem_t *rx_reorder_array_elem; int seq; diff --git a/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/TXRX/ol_rx_defrag.h b/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/TXRX/ol_rx_defrag.h index 737c29987305..7750f2456fd6 100644 --- a/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/TXRX/ol_rx_defrag.h +++ b/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/TXRX/ol_rx_defrag.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2014 The Linux Foundation. All rights reserved. + * Copyright (c) 2011-2014, 2017 The Linux Foundation. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -165,7 +165,7 @@ ol_rx_reorder_flush_frag( htt_pdev_handle htt_pdev, struct ol_txrx_peer_t *peer, unsigned tid, - int seq_num); + u_int16_t seq_num); static inline void xor_block( diff --git a/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/TXRX/ol_rx_reorder.c b/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/TXRX/ol_rx_reorder.c index e1ffff092a92..05f54907bb50 100644 --- a/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/TXRX/ol_rx_reorder.c +++ b/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/TXRX/ol_rx_reorder.c @@ -583,6 +583,14 @@ ol_rx_flush_handler( struct ol_rx_reorder_array_elem_t *rx_reorder_array_elem; htt_pdev_handle htt_pdev = pdev->htt_pdev; + if (tid >= OL_TXRX_NUM_EXT_TIDS) { + TXRX_PRINT(TXRX_PRINT_LEVEL_ERR, + "%s: invalid tid, %u\n", + __FUNCTION__, + tid); + return; + } + peer = ol_txrx_peer_find_by_id(pdev, peer_id); if (peer) { vdev = peer->vdev; @@ -622,8 +630,8 @@ ol_rx_pn_ind_handler( ol_txrx_pdev_handle pdev, u_int16_t peer_id, u_int8_t tid, - int seq_num_start, - int seq_num_end, + u_int16_t seq_num_start, + u_int16_t seq_num_end, u_int8_t pn_ie_cnt, u_int8_t *pn_ie) { @@ -635,7 +643,8 @@ ol_rx_pn_ind_handler( adf_nbuf_t head_msdu = NULL; adf_nbuf_t tail_msdu = NULL; htt_pdev_handle htt_pdev = pdev->htt_pdev; - int seq_num, i=0; + u_int16_t seq_num; + int i=0; peer = ol_txrx_peer_find_by_id(pdev, peer_id); diff --git a/drivers/staging/qcacld-2.0/CORE/MAC/src/cfg/cfgProcMsg.c b/drivers/staging/qcacld-2.0/CORE/MAC/src/cfg/cfgProcMsg.c index f81af89754ca..b96463fbbd86 100644 --- a/drivers/staging/qcacld-2.0/CORE/MAC/src/cfg/cfgProcMsg.c +++ b/drivers/staging/qcacld-2.0/CORE/MAC/src/cfg/cfgProcMsg.c @@ -2698,7 +2698,8 @@ ProcSetReqInternal(tpAniSirGlobal pMac, tANI_U16 length, tANI_U32 *pParam, tANI_ // Process string parameter else { - if (valueLenRoundedUp4 > length) + if ((valueLenRoundedUp4 > length) || + (valueLen > CFG_MAX_STR_LEN)) { PELOGE(cfgLog(pMac, LOGE, FL("Invalid string length %d" "in set param %d (tot %d)"), valueLen, diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/ol_htt_rx_api.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/ol_htt_rx_api.h index b8e98250a4be..ba043dbdc4e6 100644 --- a/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/ol_htt_rx_api.h +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/ol_htt_rx_api.h @@ -833,8 +833,8 @@ void htt_rx_frag_ind_flush_seq_num_range( htt_pdev_handle pdev, adf_nbuf_t rx_frag_ind_msg, - int *seq_num_start, - int *seq_num_end); + u_int16_t *seq_num_start, + u_int16_t *seq_num_end); /** * @brief Return the HL rx desc size * @param pdev - the HTT instance the rx data was received on diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/ol_txrx_htt_api.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/ol_txrx_htt_api.h index 0baafe0f6bde..8d42b0f06114 100644 --- a/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/ol_txrx_htt_api.h +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/ol_txrx_htt_api.h @@ -617,8 +617,8 @@ ol_rx_pn_ind_handler( ol_txrx_pdev_handle pdev, u_int16_t peer_id, u_int8_t tid, - int seq_num_start, - int seq_num_end, + u_int16_t seq_num_start, + u_int16_t seq_num_end, u_int8_t pn_ie_cnt, u_int8_t *pn_ie); diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/WMA/wma.c b/drivers/staging/qcacld-2.0/CORE/SERVICES/WMA/wma.c index fc20de998e27..74b8300b6331 100644 --- a/drivers/staging/qcacld-2.0/CORE/SERVICES/WMA/wma.c +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/WMA/wma.c @@ -1142,6 +1142,11 @@ static int wma_vdev_start_resp_handler(void *handle, u_int8_t *cmd_param_info, return -EINVAL; } + if (resp_event->vdev_id >= wma->max_bssid) { + WMA_LOGE("Invalid vdev id received from firmware"); + return -EINVAL; + } + if (wma_is_vdev_in_ap_mode(wma, resp_event->vdev_id)) { adf_os_spin_lock_bh(&wma->dfs_ic->chan_lock); wma->dfs_ic->disable_phy_err_processing = false; @@ -3581,6 +3586,13 @@ static int wma_extscan_rsp_handler(tp_wma_handle wma, uint8_t *buf) } event = (wmi_extscan_start_stop_event_fixed_param *)buf; + + if (event->vdev_id >= wma->max_bssid) { + WMA_LOGE("%s: max vdev id's %d reached", + __func__, event->vdev_id); + return -EINVAL; + } + vdev_id = event->vdev_id; extscan_ind = vos_mem_malloc(sizeof(*extscan_ind)); if (!extscan_ind) { @@ -4025,7 +4037,7 @@ static int wma_extscan_hotlist_match_event_handler(void *handle, wmi_extscan_wlan_descriptor *src_hotlist; uint32_t numap; int j, ap_found = 0; - + uint32_t buf_len; tpAniSirGlobal pMac = (tpAniSirGlobal )vos_get_context( VOS_MODULE_ID_PE, wma->vos_context); if (!pMac) { @@ -4055,6 +4067,13 @@ static int wma_extscan_hotlist_match_event_handler(void *handle, __func__, numap); numap = WMA_EXTSCAN_MAX_HOTLIST_ENTRIES; } + buf_len = sizeof(wmi_extscan_hotlist_match_event_fixed_param) + + WMI_TLV_HDR_SIZE + + (numap * sizeof(wmi_extscan_wlan_descriptor)); + if (buf_len > len) { + WMA_LOGE("Invalid buf len from FW %d numap %d", len, numap); + return -EINVAL; + } dest_hotlist = vos_mem_malloc(sizeof(*dest_hotlist) + sizeof(*dest_ap) * numap); if (!dest_hotlist) { @@ -5742,7 +5761,9 @@ static int wma_beacon_swba_handler(void *handle, u_int8_t *event, u_int32_t len) return -EINVAL; } - for ( ; vdev_map; vdev_id++, vdev_map >>= 1) { + WMA_LOGD("vdev_map = %d", vdev_map); + for (; vdev_map && vdev_id < wma->max_bssid; + vdev_id++, vdev_map >>= 1) { if (!(vdev_map & 0x1)) continue; if (!wdi_out_cfg_is_high_latency(pdev->ctrl_pdev)) @@ -19081,6 +19102,16 @@ static int wma_tbttoffset_update_event_handler(void *handle, u_int8_t *event, } tbtt_offset_event = param_buf->fixed_param; + + if (param_buf->num_tbttoffset_list > + (UINT_MAX - sizeof(u_int32_t) - + sizeof(wmi_tbtt_offset_event_fixed_param))/ + sizeof(u_int32_t)) { + WMA_LOGE("%s: Received offset list %d greater than maximum limit", + __func__, param_buf->num_tbttoffset_list); + return -EINVAL; + } + buf = vos_mem_malloc(sizeof(wmi_tbtt_offset_event_fixed_param) + sizeof (u_int32_t) + (param_buf->num_tbttoffset_list * sizeof (u_int32_t))); @@ -21984,11 +22015,18 @@ static int wma_wow_wakeup_host_event(void *handle, u_int8_t *event, wake_info = param_buf->fixed_param; - if (!wmi_get_runtime_pm_inprogress(wma->wmi_handle)) + if (!wmi_get_runtime_pm_inprogress(wma->wmi_handle)) { + if (wake_info->vdev_id >= wma->max_bssid) { + WMA_LOGE("%s: received invalid vdev_id %d", + __func__, wake_info->vdev_id); + return -EINVAL; + } + WMA_LOGA("WOW (%d) %s vdev:%d", wake_info->wake_reason, wma_wow_wake_reason_str(wake_info->wake_reason, wma), wake_info->vdev_id); + } vos_event_set(&wma->wma_resume_event); @@ -22035,6 +22073,12 @@ static int wma_wow_wakeup_host_event(void *handle, u_int8_t *event, #ifdef FEATURE_WLAN_SCAN_PNO case WOW_REASON_NLOD: wma_wow_wake_up_stats(wma, NULL, 0, WOW_REASON_NLOD); + if (wake_info->vdev_id >= wma->max_bssid) { + WMA_LOGE("%s: received invalid vdev_id %d", + __func__, wake_info->vdev_id); + return -EINVAL; + } + node = &wma->interfaces[wake_info->vdev_id]; if (node) { WMA_LOGD("NLO match happened"); @@ -33081,6 +33125,11 @@ static int wma_sap_ofl_add_sta_handler(void *handle, u_int8_t *data, sta_add_event = param_buf->fixed_param; buf_ptr = (u_int8_t *)param_buf->bufp; + if (sta_add_event->data_len > MAX_CONNECT_REQ_LENGTH) { + WMA_LOGE("%s: Received data_len %d greater than max", + __func__, sta_add_event->data_len); + return 0; + } add_sta_req = vos_mem_malloc(sizeof(*add_sta_req)); if (!add_sta_req) { WMA_LOGE("%s: Failed to alloc memory for sap_ofl_add_sta_event", diff --git a/drivers/staging/qcacld-2.0/CORE/SVC/src/ptt/wlan_ptt_sock_svc.c b/drivers/staging/qcacld-2.0/CORE/SVC/src/ptt/wlan_ptt_sock_svc.c index 2ed05806878e..4558ee84e130 100644 --- a/drivers/staging/qcacld-2.0/CORE/SVC/src/ptt/wlan_ptt_sock_svc.c +++ b/drivers/staging/qcacld-2.0/CORE/SVC/src/ptt/wlan_ptt_sock_svc.c @@ -245,6 +245,7 @@ static int ptt_sock_rx_nlink_msg (struct sk_buff * skb) */ static void ptt_cmd_handler(const void *data, int data_len, void *ctx, int pid) { + uint16_t length; ptt_app_reg_req *payload; struct nlattr *tb[CLD80211_ATTR_MAX + 1]; @@ -259,6 +260,23 @@ static void ptt_cmd_handler(const void *data, int data_len, void *ctx, int pid) } payload = (ptt_app_reg_req *)(nla_data(tb[CLD80211_ATTR_DATA])); + length = be16_to_cpu(payload->wmsg.length); + if ((USHRT_MAX - length) < (sizeof(payload->radio) + sizeof(tAniHdr))) { + PTT_TRACE(VOS_TRACE_LEVEL_ERROR, + "u16 overflow length %d %zu %zu", + length, + sizeof(payload->radio), + sizeof(tAniHdr)); + return; + } + + if (nla_len(tb[CLD80211_ATTR_DATA]) < (length + + sizeof(payload->radio) + + sizeof(tAniHdr))) { + PTT_TRACE(VOS_TRACE_LEVEL_ERROR, "ATTR_DATA len check failed"); + return; + } + switch (payload->wmsg.type) { case ANI_MSG_APP_REG_REQ: ptt_sock_send_msg_to_app(&payload->wmsg, payload->radio, diff --git a/drivers/staging/qcacld-2.0/CORE/UTILS/PKTLOG/pktlog_internal.c b/drivers/staging/qcacld-2.0/CORE/UTILS/PKTLOG/pktlog_internal.c index 1e6c1f5515a1..8227c0673aae 100644 --- a/drivers/staging/qcacld-2.0/CORE/UTILS/PKTLOG/pktlog_internal.c +++ b/drivers/staging/qcacld-2.0/CORE/UTILS/PKTLOG/pktlog_internal.c @@ -307,6 +307,10 @@ process_tx_info(struct ol_txrx_pdev_t *txrx_pdev, */ txctl_log.priv.frm_hdr = frm_hdr; adf_os_assert(txctl_log.priv.txdesc_ctl); + adf_os_assert(pl_hdr.size < sizeof(txctl_log.priv.txdesc_ctl)); + pl_hdr.size = (pl_hdr.size > sizeof(txctl_log.priv.txdesc_ctl)) + ? sizeof(txctl_log.priv.txdesc_ctl) : + pl_hdr.size; adf_os_mem_copy((void *)&txctl_log.priv.txdesc_ctl, ((void *)data + sizeof(struct ath_pktlog_hdr)), pl_hdr.size); diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index 29b3bac8bf52..f68c389a72d2 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c @@ -1140,16 +1140,15 @@ static int acm_probe(struct usb_interface *intf, while (buflen > 0) { elength = buffer[0]; - if (!elength) { - dev_err(&intf->dev, "skipping garbage byte\n"); - elength = 1; - goto next_desc; + if ((buflen < elength) || (elength < 3)) { + dev_err(&intf->dev, "invalid descriptor buffer length\n"); + break; } + if (buffer[1] != USB_DT_CS_INTERFACE) { dev_err(&intf->dev, "skipping garbage\n"); goto next_desc; } - elength = buffer[0]; switch (buffer[2]) { case USB_CDC_UNION_TYPE: /* we've found it */ diff --git a/drivers/usb/class/cdc-wdm.c b/drivers/usb/class/cdc-wdm.c index a81f9dd7ee97..ba154a6ec0cd 100644 --- a/drivers/usb/class/cdc-wdm.c +++ b/drivers/usb/class/cdc-wdm.c @@ -881,7 +881,12 @@ static int wdm_probe(struct usb_interface *intf, const struct usb_device_id *id) if (!buffer) goto err; - while (buflen > 2) { + while (buflen > 0) { + if ((buflen < buffer[0]) || (buffer[0] < 3)) { + dev_err(&intf->dev, "invalid descriptor buffer length\n"); + goto err; + } + if (buffer[1] != USB_DT_CS_INTERFACE) { dev_err(&intf->dev, "skipping garbage\n"); goto next_desc; diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c index d9ce4e3583e7..26270e9473de 100644 --- a/net/ipv4/raw.c +++ b/net/ipv4/raw.c @@ -483,11 +483,16 @@ static int raw_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, u8 tos; int err; struct ip_options_data opt_copy; + int hdrincl; err = -EMSGSIZE; if (len > 0xFFFF) goto out; + /* hdrincl should be READ_ONCE(inet->hdrincl) + * but READ_ONCE() doesn't work with bit fields + */ + hdrincl = inet->hdrincl; /* * Check the flags. */ @@ -560,7 +565,7 @@ static int raw_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, /* Linux does not mangle headers on raw sockets, * so that IP options + IP_HDRINCL is non-sense. */ - if (inet->hdrincl) + if (hdrincl) goto done; if (ipc.opt->opt.srr) { if (!daddr) @@ -582,12 +587,12 @@ static int raw_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, flowi4_init_output(&fl4, ipc.oif, sk->sk_mark, tos, RT_SCOPE_UNIVERSE, - inet->hdrincl ? IPPROTO_RAW : sk->sk_protocol, + hdrincl ? IPPROTO_RAW : sk->sk_protocol, inet_sk_flowi_flags(sk) | - (inet->hdrincl ? FLOWI_FLAG_KNOWN_NH : 0), + (hdrincl ? FLOWI_FLAG_KNOWN_NH : 0), daddr, saddr, 0, 0, sk->sk_uid); - if (!inet->hdrincl) { + if (!hdrincl) { err = raw_probe_proto_opt(&fl4, msg); if (err) goto done; @@ -609,7 +614,7 @@ static int raw_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, goto do_confirm; back_from_confirm: - if (inet->hdrincl) + if (hdrincl) err = raw_send_hdrinc(sk, &fl4, msg->msg_iov, len, &rt, msg->msg_flags); diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c index 4f802a56c50b..577d9a0d32c8 100644 --- a/net/netlink/af_netlink.c +++ b/net/netlink/af_netlink.c @@ -232,6 +232,9 @@ static int __netlink_deliver_tap_skb(struct sk_buff *skb, struct sock *sk = skb->sk; int ret = -ENOMEM; + if (!net_eq(dev_net(dev), sock_net(sk))) + return 0; + dev_hold(dev); if (is_vmalloc_addr(skb->head)) diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 5f8185397195..2a139a07e447 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -495,6 +495,14 @@ nl80211_bss_select_policy[NL80211_BSS_SELECT_ATTR_MAX + 1] = { }, }; +/* policy for packet pattern attributes */ +static const struct nla_policy +nl80211_packet_pattern_policy[MAX_NL80211_PKTPAT + 1] = { + [NL80211_PKTPAT_MASK] = { .type = NLA_BINARY, }, + [NL80211_PKTPAT_PATTERN] = { .type = NLA_BINARY, }, + [NL80211_PKTPAT_OFFSET] = { .type = NLA_U32 }, +}; + static int nl80211_prepare_wdev_dump(struct sk_buff *skb, struct netlink_callback *cb, struct cfg80211_registered_device **rdev, @@ -9290,7 +9298,7 @@ static int nl80211_set_wowlan(struct sk_buff *skb, struct genl_info *info) u8 *mask_pat; nla_parse(pat_tb, MAX_NL80211_PKTPAT, nla_data(pat), - nla_len(pat), NULL); + nla_len(pat), nl80211_packet_pattern_policy); err = -EINVAL; if (!pat_tb[NL80211_PKTPAT_MASK] || !pat_tb[NL80211_PKTPAT_PATTERN]) @@ -9518,7 +9526,7 @@ static int nl80211_parse_coalesce_rule(struct cfg80211_registered_device *rdev, u8 *mask_pat; nla_parse(pat_tb, MAX_NL80211_PKTPAT, nla_data(pat), - nla_len(pat), NULL); + nla_len(pat), nl80211_packet_pattern_policy); if (!pat_tb[NL80211_PKTPAT_MASK] || !pat_tb[NL80211_PKTPAT_PATTERN]) return -EINVAL; diff --git a/security/keys/encrypted-keys/encrypted.c b/security/keys/encrypted-keys/encrypted.c index 8e1c0099bb66..57e578888e0f 100644 --- a/security/keys/encrypted-keys/encrypted.c +++ b/security/keys/encrypted-keys/encrypted.c @@ -141,23 +141,22 @@ static int valid_ecryptfs_desc(const char *ecryptfs_desc) */ static int valid_master_desc(const char *new_desc, const char *orig_desc) { - if (!memcmp(new_desc, KEY_TRUSTED_PREFIX, KEY_TRUSTED_PREFIX_LEN)) { - if (strlen(new_desc) == KEY_TRUSTED_PREFIX_LEN) - goto out; - if (orig_desc) - if (memcmp(new_desc, orig_desc, KEY_TRUSTED_PREFIX_LEN)) - goto out; - } else if (!memcmp(new_desc, KEY_USER_PREFIX, KEY_USER_PREFIX_LEN)) { - if (strlen(new_desc) == KEY_USER_PREFIX_LEN) - goto out; - if (orig_desc) - if (memcmp(new_desc, orig_desc, KEY_USER_PREFIX_LEN)) - goto out; - } else - goto out; + int prefix_len; + + if (!strncmp(new_desc, KEY_TRUSTED_PREFIX, KEY_TRUSTED_PREFIX_LEN)) + prefix_len = KEY_TRUSTED_PREFIX_LEN; + else if (!strncmp(new_desc, KEY_USER_PREFIX, KEY_USER_PREFIX_LEN)) + prefix_len = KEY_USER_PREFIX_LEN; + else + return -EINVAL; + + if (!new_desc[prefix_len]) + return -EINVAL; + + if (orig_desc && strncmp(new_desc, orig_desc, prefix_len)) + return -EINVAL; + return 0; -out: - return -EINVAL; } /* |