aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPatrick Tjin <pattjin@google.com>2016-11-16 23:04:45 -0800
committerPatrick Tjin <pattjin@google.com>2016-11-16 23:04:45 -0800
commit226dafe7f6f62bcedd8b07ca9c21e654fb360dd5 (patch)
treee6d80e56803cf56c6e149969f480490e03ea13b9
parentbd96fbf88cb586b65a04683ad3abbf7006857f31 (diff)
parent6237296f142c5d17e80408707fb2ae0cedd5a280 (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.c2
-rw-r--r--drivers/input/touchscreen/synaptics_dsx_htc_2.6/synaptics_dsx_fw_update.c183
-rw-r--r--drivers/media/platform/msm/camera_v2/sensor/actuator/msm_actuator.c2
-rw-r--r--drivers/staging/android/binder.c6
-rwxr-xr-xdrivers/staging/android/ion/ion.c23
-rw-r--r--drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_assoc.c17
-rw-r--r--drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_cfg80211.c8
-rw-r--r--drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_hostapd.c18
-rw-r--r--drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_ocb.c11
-rw-r--r--kernel/events/core.c7
-rw-r--r--kernel/trace/ring_buffer.c9
-rw-r--r--mm/memory.c14
-rw-r--r--sound/core/info.c4
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: