diff options
author | Patrick Tjin <pattjin@google.com> | 2016-11-16 23:04:45 -0800 |
---|---|---|
committer | Patrick Tjin <pattjin@google.com> | 2016-11-16 23:04:45 -0800 |
commit | 226dafe7f6f62bcedd8b07ca9c21e654fb360dd5 (patch) | |
tree | e6d80e56803cf56c6e149969f480490e03ea13b9 | |
parent | bd96fbf88cb586b65a04683ad3abbf7006857f31 (diff) | |
parent | 6237296f142c5d17e80408707fb2ae0cedd5a280 (diff) |
Merge branch 'android-msm-marlin-3.18-ndr-factoryrom' into android-msm-marlin-3.18-nyc-mr1android-7.1.1_r0.20
Security January 2017.1
Change-Id: I324316cdb5874580139d8ccac645bb4fba49842f
-rw-r--r-- | drivers/input/misc/vl53L0/stmvl53l0_module.c | 2 | ||||
-rw-r--r-- | drivers/input/touchscreen/synaptics_dsx_htc_2.6/synaptics_dsx_fw_update.c | 183 | ||||
-rw-r--r-- | drivers/media/platform/msm/camera_v2/sensor/actuator/msm_actuator.c | 2 | ||||
-rw-r--r-- | drivers/staging/android/binder.c | 6 | ||||
-rwxr-xr-x | drivers/staging/android/ion/ion.c | 23 | ||||
-rw-r--r-- | drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_assoc.c | 17 | ||||
-rw-r--r-- | drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_cfg80211.c | 8 | ||||
-rw-r--r-- | drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_hostapd.c | 18 | ||||
-rw-r--r-- | drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_ocb.c | 11 | ||||
-rw-r--r-- | kernel/events/core.c | 7 | ||||
-rw-r--r-- | kernel/trace/ring_buffer.c | 9 | ||||
-rw-r--r-- | mm/memory.c | 14 | ||||
-rw-r--r-- | sound/core/info.c | 4 |
13 files changed, 239 insertions, 65 deletions
diff --git a/drivers/input/misc/vl53L0/stmvl53l0_module.c b/drivers/input/misc/vl53L0/stmvl53l0_module.c index 0028e527857f..cc27309fc4e2 100644 --- a/drivers/input/misc/vl53L0/stmvl53l0_module.c +++ b/drivers/input/misc/vl53L0/stmvl53l0_module.c @@ -2483,6 +2483,8 @@ static int stmvl53l0_ioctl_handler(struct file *file, if (!data->enable_ps_sensor) stmvl53l0_start(data, 3, NORMAL_MODE); + memset(&RangingMeasurementData, 0, sizeof(RangingMeasurementData)); + for (i = 0; i < RANGE_MEASUREMENT_TIMES;) { Status = papi_func_tbl->PerformSingleRangingMeasurement(vl53l0_dev, &RangingMeasurementData); diff --git a/drivers/input/touchscreen/synaptics_dsx_htc_2.6/synaptics_dsx_fw_update.c b/drivers/input/touchscreen/synaptics_dsx_htc_2.6/synaptics_dsx_fw_update.c index 05f13b427739..f7d5dbdd69b5 100644 --- a/drivers/input/touchscreen/synaptics_dsx_htc_2.6/synaptics_dsx_fw_update.c +++ b/drivers/input/touchscreen/synaptics_dsx_htc_2.6/synaptics_dsx_fw_update.c @@ -771,6 +771,21 @@ static struct synaptics_rmi4_fwu_handle *fwu; DECLARE_COMPLETION(fwu_remove_complete); DEFINE_MUTEX(fwu_sysfs_mutex); +/* Check offset + size <= bound. true if in bounds, false otherwise. */ +static bool in_bounds(unsigned long offset, unsigned long size, + unsigned long bound) +{ + if (offset > bound || size > bound) { + pr_err("%s: %lu or %lu > %lu\n", __func__, offset, size, bound); + return false; + } + if (offset > (bound - size)) { + pr_err("%s: %lu > %lu - %lu\n", __func__, offset, size, bound); + return false; + } + return true; +} + #ifdef HTC_FEATURE static uint32_t syn_crc(uint16_t *data, uint32_t len) { @@ -966,8 +981,10 @@ static void fwu_compare_partition_tables(void) return; } -static void fwu_parse_partition_table(const unsigned char *partition_table, - struct block_count *blkcount, struct physical_address *phyaddr) +static int fwu_parse_partition_table(const unsigned char *partition_table, + unsigned long len, + struct block_count *blkcount, + struct physical_address *phyaddr) { unsigned char ii; unsigned char index; @@ -979,6 +996,11 @@ static void fwu_parse_partition_table(const unsigned char *partition_table, for (ii = 0; ii < fwu->partitions; ii++) { index = ii * 8 + 2; + if (!in_bounds(index, sizeof(*ptable), len)) { + pr_err("%s: %d/%d not in bounds\n", __func__, ii, + fwu->partitions); + return -EINVAL; + } ptable = (struct partition_table *)&partition_table[index]; partition_length = ptable->partition_length_15_8 << 8 | ptable->partition_length_7_0; @@ -987,7 +1009,7 @@ static void fwu_parse_partition_table(const unsigned char *partition_table, dev_dbg(rmi4_data->pdev->dev.parent, "%s: Partition entry %d:\n", __func__, ii); - for (offset = 0; offset < 8; offset++) { + for (offset = 0; offset < sizeof(*ptable); offset++) { dev_dbg(rmi4_data->pdev->dev.parent, "%s: 0x%02x\n", __func__, @@ -1077,16 +1099,17 @@ static void fwu_parse_partition_table(const unsigned char *partition_table, }; } - return; + return 0; } -static void fwu_parse_image_header_10_utility(const unsigned char *image) +static int fwu_parse_image_header_10_utility(const unsigned char *image) { unsigned char ii; unsigned char num_of_containers; unsigned int addr; unsigned int container_id; unsigned int length; + unsigned int content_offset; const unsigned char *content; struct container_descriptor *descriptor; @@ -1099,15 +1122,22 @@ static void fwu_parse_image_header_10_utility(const unsigned char *image) if (ii >= MAX_UTILITY_PARAMS) continue; addr = le_to_uint(fwu->img.utility.data + (ii * 4)); + if (!in_bounds(addr, sizeof(*descriptor), fwu->image_size)) + return -EINVAL; descriptor = (struct container_descriptor *)(image + addr); container_id = descriptor->container_id[0] | descriptor->container_id[1] << 8; - content = image + le_to_uint(descriptor->content_address); + content_offset = le_to_uint(descriptor->content_address); length = le_to_uint(descriptor->content_length); + if (!in_bounds(content_offset, length, fwu->image_size)) + return -EINVAL; + content = image + content_offset; switch (container_id) { case UTILITY_PARAMETER_CONTAINER: fwu->img.utility_param[ii].data = content; fwu->img.utility_param[ii].size = length; + if (length < sizeof(content[0])) + return -EINVAL; fwu->img.utility_param_id[ii] = content[0]; break; default: @@ -1115,28 +1145,36 @@ static void fwu_parse_image_header_10_utility(const unsigned char *image) }; } - return; + return 0; } -static void fwu_parse_image_header_10_bootloader(const unsigned char *image) +static int fwu_parse_image_header_10_bootloader(const unsigned char *image) { unsigned char ii; unsigned char num_of_containers; unsigned int addr; unsigned int container_id; unsigned int length; + unsigned int content_offset; const unsigned char *content; struct container_descriptor *descriptor; + if (fwu->img.bootloader.size < 4) + return -EINVAL; num_of_containers = (fwu->img.bootloader.size - 4) / 4; for (ii = 1; ii <= num_of_containers; ii++) { addr = le_to_uint(fwu->img.bootloader.data + (ii * 4)); + if (!in_bounds(addr, sizeof(*descriptor), fwu->image_size)) + return -EINVAL; descriptor = (struct container_descriptor *)(image + addr); container_id = descriptor->container_id[0] | descriptor->container_id[1] << 8; - content = image + le_to_uint(descriptor->content_address); + content_offset = le_to_uint(descriptor->content_address); length = le_to_uint(descriptor->content_length); + if (!in_bounds(content_offset, length, fwu->image_size)) + return -EINVAL; + content = image + content_offset; switch (container_id) { case BL_IMAGE_CONTAINER: fwu->img.bl_image.data = content; @@ -1157,29 +1195,36 @@ static void fwu_parse_image_header_10_bootloader(const unsigned char *image) }; } - return; + return 0; } -static void fwu_parse_image_header_10(void) +static int fwu_parse_image_header_10(void) { unsigned char ii; unsigned char num_of_containers; unsigned int addr; unsigned int offset; + unsigned int content_offset; unsigned int container_id; unsigned int length; + unsigned int image_size; const unsigned char *image; const unsigned char *content; struct container_descriptor *descriptor; struct image_header_10 *header; image = fwu->image; + image_size = fwu->image_size; + if (image_size < sizeof(*header)) + return -EINVAL; header = (struct image_header_10 *)image; fwu->img.checksum = le_to_uint(header->checksum); /* address of top level container */ offset = le_to_uint(header->top_level_container_start_addr); + if (!in_bounds(offset, sizeof(*descriptor), image_size)) + return -EINVAL; descriptor = (struct container_descriptor *)(image + offset); /* address of top level container content */ @@ -1187,13 +1232,20 @@ static void fwu_parse_image_header_10(void) num_of_containers = le_to_uint(descriptor->content_length) / 4; for (ii = 0; ii < num_of_containers; ii++) { + if (!in_bounds(offset, 4, image_size)) + return -EINVAL; addr = le_to_uint(image + offset); offset += 4; + if (!in_bounds(addr, sizeof(*descriptor), image_size)) + return -EINVAL; descriptor = (struct container_descriptor *)(image + addr); container_id = descriptor->container_id[0] | descriptor->container_id[1] << 8; - content = image + le_to_uint(descriptor->content_address); + content_offset = le_to_uint(descriptor->content_address); length = le_to_uint(descriptor->content_length); + if (!in_bounds(content_offset, length, image_size)) + return -EINVAL; + content = image + content_offset; switch (container_id) { case UI_CONTAINER: case CORE_CODE_CONTAINER: @@ -1209,12 +1261,14 @@ static void fwu_parse_image_header_10(void) fwu->img.bl_version = *content; fwu->img.bootloader.data = content; fwu->img.bootloader.size = length; - fwu_parse_image_header_10_bootloader(image); + if (fwu_parse_image_header_10_bootloader(image)) + return -EINVAL; break; case UTILITY_CONTAINER: fwu->img.utility.data = content; fwu->img.utility.size = length; - fwu_parse_image_header_10_utility(image); + if (fwu_parse_image_header_10_utility(image)) + return -EINVAL; break; case GUEST_CODE_CONTAINER: fwu->img.contains_guest_code = true; @@ -1239,6 +1293,8 @@ static void fwu_parse_image_header_10(void) break; case GENERAL_INFORMATION_CONTAINER: fwu->img.contains_firmware_id = true; + if (length < 4 + 4) + return -EINVAL; fwu->img.firmware_id = le_to_uint(content + 4); break; default: @@ -1246,10 +1302,10 @@ static void fwu_parse_image_header_10(void) } } - return; + return 0; } -static void fwu_parse_image_header_05_06(void) +static int fwu_parse_image_header_05_06(void) { int retval; const unsigned char *image; @@ -1257,6 +1313,8 @@ static void fwu_parse_image_header_05_06(void) struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data; image = fwu->image; + if (fwu->image_size < sizeof(*header)) + return -EINVAL; header = (struct image_header_05_06 *)image; fwu->img.checksum = le_to_uint(header->checksum); @@ -1269,18 +1327,51 @@ static void fwu_parse_image_header_05_06(void) fwu->img.ui_firmware.size = le_to_uint(header->firmware_size); if (fwu->img.ui_firmware.size) { - fwu->img.ui_firmware.data = image + IMAGE_AREA_OFFSET; - if (fwu->img.contains_bootloader) - fwu->img.ui_firmware.data += fwu->img.bootloader_size; + unsigned int ui_firmware_offset = IMAGE_AREA_OFFSET; + + if (fwu->img.contains_bootloader) { + if (!in_bounds(ui_firmware_offset, + fwu->img.bootloader_size, + fwu->image_size)) { + return -EINVAL; + } + ui_firmware_offset += fwu->img.bootloader_size; + } + if (!in_bounds(ui_firmware_offset, + fwu->img.ui_firmware.size, + fwu->image_size)) { + return -EINVAL; + } + fwu->img.ui_firmware.data = image + ui_firmware_offset; } - if ((fwu->img.bl_version == BL_V6) && header->options_tddi) + if ((fwu->img.bl_version == BL_V6) && header->options_tddi) { + if (!in_bounds(IMAGE_AREA_OFFSET, + fwu->img.ui_firmware.size, + fwu->image_size)) { + return -EINVAL; + } fwu->img.ui_firmware.data = image + IMAGE_AREA_OFFSET; + } fwu->img.ui_config.size = le_to_uint(header->config_size); if (fwu->img.ui_config.size) { - fwu->img.ui_config.data = fwu->img.ui_firmware.data + + unsigned int ui_firmware_end; + + if (fwu->img.ui_firmware.data < image) + return -EINVAL; + if (!in_bounds(fwu->img.ui_firmware.data - image, + fwu->img.ui_firmware.size, + fwu->image_size)) { + return -EINVAL; + } + ui_firmware_end = fwu->img.ui_firmware.data - image + fwu->img.ui_firmware.size; + if (!in_bounds(ui_firmware_end, fwu->img.ui_config.size, + fwu->image_size)) { + return -EINVAL; + } + fwu->img.ui_config.data = image + ui_firmware_end; } if ((fwu->img.bl_version == BL_V5 && fwu->img.contains_bootloader) || @@ -1292,6 +1383,11 @@ static void fwu_parse_image_header_05_06(void) if (fwu->img.contains_disp_config) { fwu->img.disp_config_offset = le_to_uint(header->dsp_cfg_addr); fwu->img.dp_config.size = le_to_uint(header->dsp_cfg_size); + if (!in_bounds(fwu->img.disp_config_offset, + fwu->img.dp_config.size, + fwu->image_size)) { + return -EINVAL; + } fwu->img.dp_config.data = image + fwu->img.disp_config_offset; } else { retval = secure_memcpy(fwu->img.cstmr_product_id, @@ -1323,28 +1419,41 @@ static void fwu_parse_image_header_05_06(void) } fwu->img.product_id[PRODUCT_ID_SIZE] = 0; + if (LOCKDOWN_SIZE > IMAGE_AREA_OFFSET) + return -EINVAL; + if (fwu->image_size < IMAGE_AREA_OFFSET) + return -EINVAL; fwu->img.lockdown.size = LOCKDOWN_SIZE; fwu->img.lockdown.data = image + IMAGE_AREA_OFFSET - LOCKDOWN_SIZE; - return; + return 0; } static int fwu_parse_image_info(void) { + int parse_retval; struct image_header_10 *header; struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data; + unsigned int image_size = 0; header = (struct image_header_10 *)fwu->image; - + if (!header) + return -EINVAL; + image_size = fwu->image_size; + if (image_size < sizeof(struct image_header_05_06) && + image_size < sizeof(struct image_header_10)) { + return -EINVAL; + } + /* This is clearing img, not image. */ memset(&fwu->img, 0x00, sizeof(fwu->img)); switch (header->major_header_version) { case IMAGE_HEADER_VERSION_10: - fwu_parse_image_header_10(); + parse_retval = fwu_parse_image_header_10(); break; case IMAGE_HEADER_VERSION_05: case IMAGE_HEADER_VERSION_06: - fwu_parse_image_header_05_06(); + parse_retval = fwu_parse_image_header_05_06(); break; default: dev_err(rmi4_data->pdev->dev.parent, @@ -1353,6 +1462,10 @@ static int fwu_parse_image_info(void) return -EINVAL; } + if (parse_retval != 0) { + return -EINVAL; + } + if (fwu->bl_version == BL_V7 || fwu->bl_version == BL_V8) { if (!fwu->img.contains_flash_config) { dev_err(rmi4_data->pdev->dev.parent, @@ -1361,9 +1474,12 @@ static int fwu_parse_image_info(void) return -EINVAL; } - fwu_parse_partition_table(fwu->img.fl_config.data, - &fwu->img.blkcount, &fwu->img.phyaddr); - + if (fwu_parse_partition_table(fwu->img.fl_config.data, + fwu->img.fl_config.size, + &fwu->img.blkcount, + &fwu->img.phyaddr)) { + return -EINVAL; + } fwu_compare_partition_tables(); } else { fwu->new_partition_table = false; @@ -1980,7 +2096,11 @@ static int fwu_read_f34_v7_queries(void) return retval; } - fwu_parse_partition_table(ptable, &fwu->blkcount, &fwu->phyaddr); + if (fwu_parse_partition_table(ptable, fwu->partition_table_bytes, + &fwu->blkcount, &fwu->phyaddr)) { + kfree(ptable); + return -EINVAL; + } if (fwu->blkcount.dp_config) fwu->flash_properties.has_disp_config = 1; @@ -3209,6 +3329,9 @@ static int fwu_write_utility_parameter(void) struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data; utility_param_size = fwu->blkcount.utility_param * fwu->block_size; + /* See remaining_size below for reason for '4' */ + if (utility_param_size < 4) + return -EINVAL; retval = fwu_allocate_read_config_buf(utility_param_size); if (retval < 0) return retval; @@ -4910,6 +5033,7 @@ int synaptics_config_updater(struct synaptics_dsx_board_data *bdata) rmi4_data->stay_awake = true; + memset(config_id, 0, sizeof(config_id)); if (fwu->bl_version == BL_V7) config_id_size = V7_CONFIG_ID_SIZE; else @@ -4928,6 +5052,7 @@ int synaptics_config_updater(struct synaptics_dsx_board_data *bdata) } memset(str_buf, 0, sizeof(str_buf)); + memset(tmp_buf, 0, sizeof(tmp_buf)); for (ii = 0; ii < config_id_size; ii++) { snprintf(tmp_buf, 3, "%02x ", config_id[ii]); strlcat(str_buf, tmp_buf, sizeof(str_buf)); diff --git a/drivers/media/platform/msm/camera_v2/sensor/actuator/msm_actuator.c b/drivers/media/platform/msm/camera_v2/sensor/actuator/msm_actuator.c index bf3973888573..a700f836061c 100644 --- a/drivers/media/platform/msm/camera_v2/sensor/actuator/msm_actuator.c +++ b/drivers/media/platform/msm/camera_v2/sensor/actuator/msm_actuator.c @@ -1559,11 +1559,13 @@ static long msm_actuator_subdev_ioctl(struct v4l2_subdev *sd, pr_err("a_ctrl->i2c_client.i2c_func_tbl NULL\n"); return -EINVAL; } + mutex_lock(a_ctrl->actuator_mutex); rc = msm_actuator_power_down(a_ctrl); if (rc < 0) { pr_err("%s:%d Actuator Power down failed\n", __func__, __LINE__); } + mutex_unlock(a_ctrl->actuator_mutex); return msm_actuator_close(sd, NULL); default: return -ENOIOCTLCMD; diff --git a/drivers/staging/android/binder.c b/drivers/staging/android/binder.c index ad902dbac8fa..56f9713de523 100644 --- a/drivers/staging/android/binder.c +++ b/drivers/staging/android/binder.c @@ -2784,6 +2784,9 @@ static int binder_ioctl_set_ctx_mgr(struct file *filp) ret = -EBUSY; goto out; } + ret = security_binder_set_context_mgr(proc->tsk); + if (ret < 0) + goto out; if (uid_valid(binder_context_mgr_uid)) { if (!uid_eq(binder_context_mgr_uid, curr_euid)) { pr_err("BINDER_SET_CONTEXT_MGR bad uid %d != %d\n", @@ -2849,9 +2852,6 @@ static long binder_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) ret = binder_ioctl_set_ctx_mgr(filp); if (ret) goto err; - ret = security_binder_set_context_mgr(proc->tsk); - if (ret < 0) - goto err; break; case BINDER_THREAD_EXIT: binder_debug(BINDER_DEBUG_THREADS, "%d:%d exit\n", diff --git a/drivers/staging/android/ion/ion.c b/drivers/staging/android/ion/ion.c index 8bbbb38dc7c4..63e6b7d795f4 100755 --- a/drivers/staging/android/ion/ion.c +++ b/drivers/staging/android/ion/ion.c @@ -507,9 +507,9 @@ static int ion_handle_add(struct ion_client *client, struct ion_handle *handle) return 0; } -struct ion_handle *ion_alloc(struct ion_client *client, size_t len, +static struct ion_handle *__ion_alloc(struct ion_client *client, size_t len, size_t align, unsigned int heap_id_mask, - unsigned int flags) + unsigned int flags, bool grab_handle) { struct ion_handle *handle; struct ion_device *dev = client->dev; @@ -604,6 +604,8 @@ struct ion_handle *ion_alloc(struct ion_client *client, size_t len, return handle; mutex_lock(&client->lock); + if (grab_handle) + ion_handle_get(handle); ret = ion_handle_add(client, handle); mutex_unlock(&client->lock); if (ret) { @@ -613,6 +615,13 @@ struct ion_handle *ion_alloc(struct ion_client *client, size_t len, return handle; } + +struct ion_handle *ion_alloc(struct ion_client *client, size_t len, + size_t align, unsigned int heap_id_mask, + unsigned int flags) +{ + return __ion_alloc(client, len, align, heap_id_mask, flags, false); +} EXPORT_SYMBOL(ion_alloc); static void ion_free_nolock(struct ion_client *client, struct ion_handle *handle) @@ -1488,10 +1497,10 @@ static long ion_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { struct ion_handle *handle; - handle = ion_alloc(client, data.allocation.len, + handle = __ion_alloc(client, data.allocation.len, data.allocation.align, data.allocation.heap_id_mask, - data.allocation.flags); + data.allocation.flags, true); if (IS_ERR(handle)) return PTR_ERR(handle); @@ -1568,11 +1577,15 @@ static long ion_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) if (dir & _IOC_READ) { if (copy_to_user((void __user *)arg, &data, _IOC_SIZE(cmd))) { - if (cleanup_handle) + if (cleanup_handle) { ion_free(client, cleanup_handle); + ion_handle_put(cleanup_handle); + } return -EFAULT; } } + if (cleanup_handle) + ion_handle_put(cleanup_handle); return ret; } diff --git a/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_assoc.c b/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_assoc.c index 9d7f5965eb76..f353888ebdef 100644 --- a/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_assoc.c +++ b/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_assoc.c @@ -2744,7 +2744,7 @@ static eHalStatus roamRoamConnectStatusUpdateHandler( hdd_adapter_t *pAdapter, t case eCSR_ROAM_RESULT_IBSS_NEW_PEER: { hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); - struct station_info staInfo; + struct station_info *stainfo; pr_info ( "IBSS New Peer indication from SME " "with peerMac " MAC_ADDRESS_STR " BSSID: " MAC_ADDRESS_STR " and stationID= %d", @@ -2779,13 +2779,20 @@ static eHalStatus roamRoamConnectStatusUpdateHandler( hdd_adapter_t *pAdapter, t vosStatus, vosStatus ); } pHddStaCtx->ibss_sta_generation++; - memset(&staInfo, 0, sizeof(staInfo)); - staInfo.filled = 0; - staInfo.generation = pHddStaCtx->ibss_sta_generation; + stainfo = vos_mem_malloc(sizeof(*stainfo)); + if (stainfo == NULL) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "memory allocation for station_info failed"); + return eHAL_STATUS_FAILED_ALLOC; + } + memset(stainfo, 0, sizeof(*stainfo)); + stainfo->filled = 0; + stainfo->generation = pHddStaCtx->ibss_sta_generation; cfg80211_new_sta(pAdapter->dev, (const u8 *)pRoamInfo->peerMac, - &staInfo, GFP_KERNEL); + stainfo, GFP_KERNEL); + vos_mem_free(stainfo); if ( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == pHddStaCtx->ibss_enc_key.encType ||eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == pHddStaCtx->ibss_enc_key.encType diff --git a/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_cfg80211.c b/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_cfg80211.c index 013a2db6b2ab..e45b70456011 100644 --- a/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_cfg80211.c +++ b/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_cfg80211.c @@ -2871,7 +2871,7 @@ __wlan_hdd_cfg80211_extscan_set_ssid_hotlist(struct wiphy *wiphy, struct hdd_ext_scan_context *context; uint32_t request_id; char ssid_string[SIR_MAC_MAX_SSID_LENGTH + 1]; - int ssid_len; + int ssid_len, ssid_length; eHalStatus status; int i, rem, retval; unsigned long rc; @@ -2950,12 +2950,16 @@ __wlan_hdd_cfg80211_extscan_set_ssid_hotlist(struct wiphy *wiphy, hddLog(LOGE, FL("attr ssid failed")); goto fail; } - nla_memcpy(ssid_string, + ssid_length = nla_strlcpy(ssid_string, tb2[PARAM_SSID], sizeof(ssid_string)); hddLog(LOG1, FL("SSID %s"), ssid_string); ssid_len = strlen(ssid_string); + if (ssid_length > SIR_MAC_MAX_SSID_LENGTH) { + hddLog(LOGE, FL("Invalid ssid length")); + goto fail; + } memcpy(request->ssids[i].ssid.ssId, ssid_string, ssid_len); request->ssids[i].ssid.length = ssid_len; diff --git a/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_hostapd.c b/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_hostapd.c index 4ac29d461bfa..a1f30c238076 100644 --- a/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_hostapd.c +++ b/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_hostapd.c @@ -1825,21 +1825,27 @@ VOS_STATUS hdd_hostapd_SAPEventCB( tpSap_Event pSapEvent, v_PVOID_t usrDataForCa HDD_SAP_WAKE_LOCK_DURATION, WIFI_POWER_EVENT_WAKELOCK_SAP); { - struct station_info staInfo; v_U16_t iesLen = pSapEvent->sapevt.sapStationAssocReassocCompleteEvent.iesLen; - memset(&staInfo, 0, sizeof(staInfo)); if (iesLen <= MAX_ASSOC_IND_IE_LEN ) { - staInfo.assoc_req_ies = + struct station_info *stainfo; + stainfo = vos_mem_malloc(sizeof(*stainfo)); + if (stainfo == NULL) { + hddLog(LOGE, FL("alloc station_info failed")); + return VOS_STATUS_E_NOMEM; + } + memset(stainfo, 0, sizeof(*stainfo)); + stainfo->assoc_req_ies = (const u8 *)&pSapEvent->sapevt.sapStationAssocReassocCompleteEvent.ies[0]; - staInfo.assoc_req_ies_len = iesLen; + stainfo->assoc_req_ies_len = iesLen; #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,31)) || defined(WITH_BACKPORTS) - staInfo.filled |= STATION_INFO_ASSOC_REQ_IES; + stainfo->filled |= STATION_INFO_ASSOC_REQ_IES; #endif cfg80211_new_sta(dev, (const u8 *)&pSapEvent->sapevt.sapStationAssocReassocCompleteEvent.staMac.bytes[0], - &staInfo, GFP_KERNEL); + stainfo, GFP_KERNEL); + vos_mem_free(stainfo); } else { diff --git a/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_ocb.c b/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_ocb.c index b6494ca47e4b..95fde5eca899 100644 --- a/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_ocb.c +++ b/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_ocb.c @@ -406,10 +406,11 @@ static int hdd_ocb_register_sta(hdd_adapter_t *adapter) * * Return: A pointer to the OCB configuration struct, NULL on failure. */ -static struct sir_ocb_config *hdd_ocb_config_new(int num_channels, - int num_schedule, - int ndl_chan_list_len, - int ndl_active_state_list_len) +static +struct sir_ocb_config *hdd_ocb_config_new(uint32_t num_channels, + uint32_t num_schedule, + uint32_t ndl_chan_list_len, + uint32_t ndl_active_state_list_len) { struct sir_ocb_config *ret = 0; uint32_t len; @@ -903,7 +904,7 @@ static int __wlan_hdd_cfg80211_ocb_set_config(struct wiphy *wiphy, void *def_tx_param = NULL; uint32_t def_tx_param_size = 0; int i; - int channel_count, schedule_size; + uint32_t channel_count, schedule_size; struct sir_ocb_config *config; int rc = -EINVAL; uint8_t *mac_addr; diff --git a/kernel/events/core.c b/kernel/events/core.c index 01eab13ec0e7..b7e1e224f07e 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c @@ -1449,10 +1449,17 @@ static void perf_group_detach(struct perf_event *event) * If this was a group event with sibling events then * upgrade the siblings to singleton events by adding them * to whatever list we are on. + * If this isn't on a list, make sure we still remove the sibling's + * group_entry from this sibling_list; otherwise, when that sibling + * is later deallocated, it will try to remove itself from this + * sibling_list, which may well have been deallocated already, + * resulting in a use-after-free. */ list_for_each_entry_safe(sibling, tmp, &event->sibling_list, group_entry) { if (list) list_move_tail(&sibling->group_entry, list); + else + list_del_init(&sibling->group_entry); sibling->group_leader = sibling; /* Inherit group flags from the previous leader */ diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c index 0fc5cfedcc8c..7d370a6ebf18 100644 --- a/kernel/trace/ring_buffer.c +++ b/kernel/trace/ring_buffer.c @@ -1693,14 +1693,13 @@ int ring_buffer_resize(struct ring_buffer *buffer, unsigned long size, !cpumask_test_cpu(cpu_id, buffer->cpumask)) return size; - size = DIV_ROUND_UP(size, BUF_PAGE_SIZE); - size *= BUF_PAGE_SIZE; + nr_pages = DIV_ROUND_UP(size, BUF_PAGE_SIZE); /* we need a minimum of two pages */ - if (size < BUF_PAGE_SIZE * 2) - size = BUF_PAGE_SIZE * 2; + if (nr_pages < 2) + nr_pages = 2; - nr_pages = DIV_ROUND_UP(size, BUF_PAGE_SIZE); + size = nr_pages * BUF_PAGE_SIZE; /* * Don't succeed if resizing is disabled, as a reader might be diff --git a/mm/memory.c b/mm/memory.c index 62b30f222c09..0abbdd28fe84 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -2630,6 +2630,10 @@ static int do_anonymous_page(struct mm_struct *mm, struct vm_area_struct *vma, pte_unmap(page_table); + /* File mapping without ->vm_ops ? */ + if (vma->vm_flags & VM_SHARED) + return VM_FAULT_SIGBUS; + /* Check if we need to add a guard page to the stack */ if (check_stack_guard_page(vma, address) < 0) return VM_FAULT_SIGSEGV; @@ -3034,6 +3038,9 @@ static int do_linear_fault(struct mm_struct *mm, struct vm_area_struct *vma, - vma->vm_start) >> PAGE_SHIFT) + vma->vm_pgoff; pte_unmap(page_table); + /* The VMA was not fully populated on mmap() or missing VM_DONTEXPAND */ + if (!vma->vm_ops->fault) + return VM_FAULT_SIGBUS; if (!(flags & FAULT_FLAG_WRITE)) return do_read_fault(mm, vma, address, pmd, pgoff, flags, orig_pte); @@ -3199,11 +3206,10 @@ static int handle_pte_fault(struct mm_struct *mm, entry = ACCESS_ONCE(*pte); if (!pte_present(entry)) { if (pte_none(entry)) { - if (vma->vm_ops) { - if (likely(vma->vm_ops->fault)) - return do_linear_fault(mm, vma, address, + if (vma->vm_ops) + return do_linear_fault(mm, vma, address, pte, pmd, flags, entry); - } + return do_anonymous_page(mm, vma, address, pte, pmd, flags); } diff --git a/sound/core/info.c b/sound/core/info.c index 418b4ec43cad..a4af0ba92d30 100644 --- a/sound/core/info.c +++ b/sound/core/info.c @@ -253,6 +253,7 @@ static ssize_t snd_info_entry_write(struct file *file, const char __user *buffer struct snd_info_buffer *buf; ssize_t size = 0; loff_t pos; + unsigned long realloc_size; data = file->private_data; if (snd_BUG_ON(!data)) @@ -261,7 +262,8 @@ static ssize_t snd_info_entry_write(struct file *file, const char __user *buffer pos = *offset; if (pos < 0 || (long) pos != pos || (ssize_t) count < 0) return -EIO; - if ((unsigned long) pos + (unsigned long) count < (unsigned long) pos) + realloc_size = (unsigned long) pos + (unsigned long) count; + if (realloc_size < (unsigned long) pos || realloc_size > UINT_MAX) return -EIO; switch (entry->content) { case SNDRV_INFO_CONTENT_TEXT: |