diff --git a/block/blk-cgroup.c b/block/blk-cgroup.c index 8161090a19708684224402c59bfdb55dbbc07ef4..46ba2402c8f97441be4f69462820a7e90bf274e1 100644 --- a/block/blk-cgroup.c +++ b/block/blk-cgroup.c @@ -1078,10 +1078,8 @@ int blkcg_init_queue(struct request_queue *q) if (preloaded) radix_tree_preload_end(); - if (IS_ERR(blkg)) { - blkg_free(new_blkg); + if (IS_ERR(blkg)) return PTR_ERR(blkg); - } q->root_blkg = blkg; q->root_rl.blkg = blkg; diff --git a/drivers/amba/bus.c b/drivers/amba/bus.c index f0099360039e247c91ea39e95e6f092f7505d42c..42086ad535c564d3357a1848bcad25ac034b08c9 100644 --- a/drivers/amba/bus.c +++ b/drivers/amba/bus.c @@ -82,7 +82,8 @@ static ssize_t driver_override_store(struct device *_dev, struct amba_device *dev = to_amba_device(_dev); char *driver_override, *old = dev->driver_override, *cp; - if (count > PATH_MAX) + /* We need to keep extra room for a newline */ + if (count >= (PAGE_SIZE - 1)) return -EINVAL; driver_override = kstrndup(buf, count, GFP_KERNEL); diff --git a/drivers/char/adsprpc.c b/drivers/char/adsprpc.c index 5d4c0be5c8218e79ef3ee332b8e5ef79211419f4..2730299ee552c04d94b4054efc66a2afffbcc12a 100644 --- a/drivers/char/adsprpc.c +++ b/drivers/char/adsprpc.c @@ -64,6 +64,10 @@ #define NUM_CHANNELS 4 /* adsp,sdsp,mdsp,cdsp */ #define NUM_SESSIONS 9 /*8 compute, 1 cpz*/ +#define FASTRPC_CTX_MAGIC (0xbeeddeed) +#define FASTRPC_CTX_MAX (256) +#define FASTRPC_CTXID_MASK (0xFF0) + #define IS_CACHE_ALIGNED(x) (((x) & ((L1_CACHE_BYTES)-1)) == 0) #define FASTRPC_LINK_STATE_DOWN (0x0) @@ -173,6 +177,8 @@ struct smq_invoke_ctx { struct overlap *overs; struct overlap **overps; struct smq_msg msg; + unsigned int magic; + uint64_t ctxid; }; struct fastrpc_ctx_lst { @@ -239,6 +245,8 @@ struct fastrpc_apps { spinlock_t hlock; struct ion_client *client; struct device *dev; + spinlock_t ctxlock; + struct smq_invoke_ctx *ctxtable[FASTRPC_CTX_MAX]; }; struct fastrpc_mmap { @@ -291,6 +299,7 @@ struct fastrpc_file { struct fastrpc_apps *apps; struct fastrpc_perf perf; struct dentry *debugfs_file; + struct mutex map_mutex; }; static struct fastrpc_apps gfa; @@ -892,7 +901,8 @@ static int context_alloc(struct fastrpc_file *fl, uint32_t kernel, struct fastrpc_ioctl_invoke_attrs *invokefd, struct smq_invoke_ctx **po) { - int err = 0, bufs, size = 0; + int err = 0, bufs, ii, size = 0; + struct fastrpc_apps *me = &gfa; struct smq_invoke_ctx *ctx = 0; struct fastrpc_ctx_lst *clst = &fl->clst; struct fastrpc_ioctl_invoke *invoke = &invokefd->inv; @@ -946,11 +956,27 @@ static int context_alloc(struct fastrpc_file *fl, uint32_t kernel, ctx->pid = current->pid; ctx->tgid = current->tgid; init_completion(&ctx->work); + ctx->magic = FASTRPC_CTX_MAGIC; spin_lock(&fl->hlock); hlist_add_head(&ctx->hn, &clst->pending); spin_unlock(&fl->hlock); + spin_lock(&me->ctxlock); + for (ii = 0; ii < FASTRPC_CTX_MAX; ii++) { + if (!me->ctxtable[ii]) { + me->ctxtable[ii] = ctx; + ctx->ctxid = (ptr_to_uint64(ctx) & ~0xFFF)|(ii << 4); + break; + } + } + spin_unlock(&me->ctxlock); + VERIFY(err, ii < FASTRPC_CTX_MAX); + if (err) { + pr_err("adsprpc: out of context memory\n"); + goto bail; + } + *po = ctx; bail: if (ctx && err) @@ -972,6 +998,7 @@ static void context_save_interrupted(struct smq_invoke_ctx *ctx) static void context_free(struct smq_invoke_ctx *ctx) { int i; + struct fastrpc_apps *me = &gfa; int nbufs = REMOTE_SCALARS_INBUFS(ctx->sc) + REMOTE_SCALARS_OUTBUFS(ctx->sc); spin_lock(&ctx->fl->hlock); @@ -980,6 +1007,18 @@ static void context_free(struct smq_invoke_ctx *ctx) for (i = 0; i < nbufs; ++i) fastrpc_mmap_free(ctx->maps[i]); fastrpc_buf_free(ctx->buf, 1); + ctx->magic = 0; + ctx->ctxid = 0; + + spin_lock(&me->ctxlock); + for (i = 0; i < FASTRPC_CTX_MAX; i++) { + if (me->ctxtable[i] == ctx) { + me->ctxtable[i] = NULL; + break; + } + } + spin_unlock(&me->ctxlock); + kfree(ctx); } @@ -1393,7 +1432,7 @@ static int fastrpc_invoke_send(struct smq_invoke_ctx *ctx, msg->tid = current->pid; if (kernel) msg->pid = 0; - msg->invoke.header.ctx = ptr_to_uint64(ctx) | fl->pd; + msg->invoke.header.ctx = ctx->ctxid | fl->pd; msg->invoke.header.handle = handle; msg->invoke.header.sc = ctx->sc; msg->invoke.page.addr = ctx->buf ? ctx->buf->phys : 0; @@ -1420,6 +1459,7 @@ static void fastrpc_init(struct fastrpc_apps *me) INIT_HLIST_HEAD(&me->drivers); INIT_HLIST_HEAD(&me->maps); spin_lock_init(&me->hlock); + spin_lock_init(&me->ctxlock); mutex_init(&me->smd_mutex); me->channel = &gcinfo[0]; for (i = 0; i < NUM_CHANNELS; i++) { @@ -1578,12 +1618,19 @@ static int fastrpc_init_process(struct fastrpc_file *fl, inbuf.namelen = strlen(current->comm) + 1; inbuf.filelen = init->filelen; fl->pd = 1; + + if (!access_ok(0, (void const __user *)init->file, + init->filelen)) + goto bail; if (init->filelen) { VERIFY(err, !fastrpc_mmap_create(fl, init->filefd, 0, init->file, init->filelen, mflags, &file)); if (err) goto bail; } + if (!access_ok(1, (void const __user *)init->mem, + init->memlen)) + goto bail; inbuf.pageslen = 1; VERIFY(err, !fastrpc_mmap_create(fl, init->memfd, 0, init->mem, init->memlen, mflags, &mem)); @@ -1957,6 +2004,7 @@ static int fastrpc_internal_munmap(struct fastrpc_file *fl, int err = 0; struct fastrpc_mmap *map = 0; + mutex_lock(&fl->map_mutex); VERIFY(err, !fastrpc_mmap_remove(fl, ud->vaddrout, ud->size, &map)); if (err) goto bail; @@ -1967,6 +2015,7 @@ static int fastrpc_internal_munmap(struct fastrpc_file *fl, bail: if (err && map) fastrpc_mmap_add(map); + mutex_unlock(&fl->map_mutex); return err; } @@ -1976,9 +2025,13 @@ static int fastrpc_internal_mmap(struct fastrpc_file *fl, struct fastrpc_mmap *map = 0; int err = 0; + + mutex_lock(&fl->map_mutex); if (!fastrpc_mmap_find(fl, ud->fd, (uintptr_t)ud->vaddrin, ud->size, - ud->flags, &map)) + ud->flags, &map)) { + mutex_unlock(&fl->map_mutex); return 0; + } VERIFY(err, !fastrpc_mmap_create(fl, ud->fd, 0, (uintptr_t)ud->vaddrin, ud->size, ud->flags, &map)); @@ -1991,6 +2044,7 @@ static int fastrpc_internal_mmap(struct fastrpc_file *fl, bail: if (err && map) fastrpc_mmap_free(map); + mutex_unlock(&fl->map_mutex); return err; } @@ -2060,14 +2114,32 @@ void fastrpc_glink_notify_rx(void *handle, const void *priv, const void *pkt_priv, const void *ptr, size_t size) { struct smq_invoke_rsp *rsp = (struct smq_invoke_rsp *)ptr; - int len = size; + struct fastrpc_apps *me = &gfa; + uint32_t index; + int err = 0; - while (len >= sizeof(*rsp) && rsp) { - rsp->ctx = rsp->ctx & ~1; - context_notify_user(uint64_to_ptr(rsp->ctx), rsp->retval); - rsp++; - len = len - sizeof(*rsp); - } + VERIFY(err, (rsp && size >= sizeof(*rsp))); + if (err) + goto bail; + + index = (uint32_t)((rsp->ctx & FASTRPC_CTXID_MASK) >> 4); + VERIFY(err, index < FASTRPC_CTX_MAX); + if (err) + goto bail; + + VERIFY(err, !IS_ERR_OR_NULL(me->ctxtable[index])); + if (err) + goto bail; + + VERIFY(err, ((me->ctxtable[index]->ctxid == (rsp->ctx & ~1)) && + me->ctxtable[index]->magic == FASTRPC_CTX_MAGIC)); + if (err) + goto bail; + + context_notify_user(me->ctxtable[index], rsp->retval); +bail: + if (err) + pr_err("adsprpc: invalid response or context\n"); glink_rx_done(handle, ptr, true); } @@ -2166,6 +2238,7 @@ static int fastrpc_device_release(struct inode *inode, struct file *file) if (fl) { if (fl->debugfs_file != NULL) debugfs_remove(fl->debugfs_file); + mutex_destroy(&fl->map_mutex); fastrpc_file_free(fl); file->private_data = 0; } @@ -2476,6 +2549,7 @@ static int fastrpc_device_open(struct inode *inode, struct file *filp) fl->debugfs_file = debugfs_file; memset(&fl->perf, 0, sizeof(fl->perf)); filp->private_data = fl; + mutex_init(&fl->map_mutex); spin_lock(&me->hlock); hlist_add_head(&fl->hn, &me->drivers); spin_unlock(&me->hlock); diff --git a/drivers/char/diag/diag_dci.c b/drivers/char/diag/diag_dci.c index 4a83fc5cc68a4dbe9b3adbf60908301fe1ac3f1a..de02a1abcd6255165246edd1a5c1b69c1fbb5a41 100644 --- a/drivers/char/diag/diag_dci.c +++ b/drivers/char/diag/diag_dci.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -843,11 +843,11 @@ static void dci_process_ctrl_status(unsigned char *buf, int len, int token) { struct diag_ctrl_dci_status *header = NULL; unsigned char *temp = buf; - uint32_t read_len = 0; + unsigned int read_len = 0; uint8_t i; int peripheral_mask, status; - if (!buf || (len < sizeof(struct diag_ctrl_dci_status))) { + if (!buf || (len < 2) || (len < sizeof(struct diag_ctrl_dci_status))) { pr_err("diag: In %s, invalid buf %pK or length: %d\n", __func__, buf, len); return; @@ -863,7 +863,7 @@ static void dci_process_ctrl_status(unsigned char *buf, int len, int token) read_len += sizeof(struct diag_ctrl_dci_status); for (i = 0; i < header->count; i++) { - if (read_len > len) { + if (read_len > (len - 2)) { pr_err("diag: In %s, Invalid length len: %d\n", __func__, len); return; @@ -905,7 +905,9 @@ static void dci_process_ctrl_handshake_pkt(unsigned char *buf, int len, unsigned char *temp = buf; int err = 0; - if (!buf || (len < sizeof(struct diag_ctrl_dci_handshake_pkt))) + if (!buf) + return; + if (len < 0 || len < sizeof(struct diag_ctrl_dci_handshake_pkt)) return; if (!VALID_DCI_TOKEN(token)) @@ -1162,18 +1164,31 @@ void extract_dci_events(unsigned char *buf, int len, int data_source, struct list_head *start, *temp; struct diag_dci_client_tbl *entry = NULL; - length = *(uint16_t *)(buf + 1); /* total length of event series */ - if (length == 0) { - pr_err("diag: Incoming dci event length is invalid\n"); + if (!buf) { + pr_err("diag: In %s buffer is NULL\n", __func__); return; } /* - * Move directly to the start of the event series. 1 byte for - * event code and 2 bytes for the length field. + * 1 byte for event code and 2 bytes for the length field. * The length field indicates the total length removing the cmd_code * and the lenght field. The event parsing in that case should happen * till the end. */ + if (len < 3) { + pr_err("diag: In %s invalid len: %d\n", __func__, len); + return; + } + length = *(uint16_t *)(buf + 1); /* total length of event series */ + if ((length == 0) || (len != (length + 3))) { + pr_err("diag: Incoming dci event length: %d is invalid\n", + length); + return; + } + /* + * Move directly to the start of the event series. + * The event parsing should happen from start of event + * series till the end. + */ temp_len = 3; while (temp_len < length) { event_id_packet = *(uint16_t *)(buf + temp_len); @@ -1190,30 +1205,60 @@ void extract_dci_events(unsigned char *buf, int len, int data_source, * necessary. */ timestamp_len = 8; - memcpy(timestamp, buf + temp_len + 2, timestamp_len); + if ((temp_len + timestamp_len + 2) <= len) + memcpy(timestamp, buf + temp_len + 2, + timestamp_len); + else { + pr_err("diag: Invalid length in %s, len: %d, temp_len: %d", + __func__, len, temp_len); + return; + } } /* 13th and 14th bit represent the payload length */ if (((event_id_packet & 0x6000) >> 13) == 3) { payload_len_field = 1; - payload_len = *(uint8_t *) + if ((temp_len + timestamp_len + 3) <= len) { + payload_len = *(uint8_t *) (buf + temp_len + 2 + timestamp_len); - if (payload_len < (MAX_EVENT_SIZE - 13)) { - /* copy the payload length and the payload */ + } else { + pr_err("diag: Invalid length in %s, len: %d, temp_len: %d", + __func__, len, temp_len); + return; + } + if ((payload_len < (MAX_EVENT_SIZE - 13)) && + ((temp_len + timestamp_len + payload_len + 3) <= len)) { + /* + * Copy the payload length and the payload + * after skipping temp_len bytes for already + * parsed packet, timestamp_len for timestamp + * buffer, 2 bytes for event_id_packet. + */ memcpy(event_data + 12, buf + temp_len + 2 + timestamp_len, 1); memcpy(event_data + 13, buf + temp_len + 2 + timestamp_len + 1, payload_len); } else { - pr_err("diag: event > %d, payload_len = %d\n", - (MAX_EVENT_SIZE - 13), payload_len); + pr_err("diag: event > %d, payload_len = %d, temp_len = %d\n", + (MAX_EVENT_SIZE - 13), payload_len, temp_len); return; } } else { payload_len_field = 0; payload_len = (event_id_packet & 0x6000) >> 13; - /* copy the payload */ - memcpy(event_data + 12, buf + temp_len + 2 + + /* + * Copy the payload after skipping temp_len bytes + * for already parsed packet, timestamp_len for + * timestamp buffer, 2 bytes for event_id_packet. + */ + if ((payload_len < (MAX_EVENT_SIZE - 12)) && + ((temp_len + timestamp_len + payload_len + 2) <= len)) + memcpy(event_data + 12, buf + temp_len + 2 + timestamp_len, payload_len); + else { + pr_err("diag: event > %d, payload_len = %d, temp_len = %d\n", + (MAX_EVENT_SIZE - 12), payload_len, temp_len); + return; + } } /* Before copying the data to userspace, check if we are still @@ -1337,19 +1382,19 @@ void extract_dci_log(unsigned char *buf, int len, int data_source, int token, pr_err("diag: In %s buffer is NULL\n", __func__); return; } - - /* The first six bytes for the incoming log packet contains - * Command code (2), the length of the packet (2) and the length - * of the log (2) + /* + * The first eight bytes for the incoming log packet contains + * Command code (2), the length of the packet (2), the length + * of the log (2) and log code (2) */ - log_code = *(uint16_t *)(buf + 6); - read_bytes += sizeof(uint16_t) + 6; - if (read_bytes > len) { - pr_err("diag: Invalid length in %s, len: %d, read: %d", - __func__, len, read_bytes); + if (len < 8) { + pr_err("diag: In %s invalid len: %d\n", __func__, len); return; } + log_code = *(uint16_t *)(buf + 6); + read_bytes += sizeof(uint16_t) + 6; + /* parse through log mask table of each client and check mask */ mutex_lock(&driver->dci_mutex); list_for_each_safe(start, temp, &driver->dci_client_list) { @@ -1376,6 +1421,10 @@ void extract_dci_ext_pkt(unsigned char *buf, int len, int data_source, pr_err("diag: In %s buffer is NULL\n", __func__); return; } + if (len < (EXT_HDR_LEN + sizeof(uint8_t))) { + pr_err("diag: In %s invalid len: %d\n", __func__, len); + return; + } version = *(uint8_t *)buf + 1; if (version < EXT_HDR_VERSION) { @@ -1387,10 +1436,6 @@ void extract_dci_ext_pkt(unsigned char *buf, int len, int data_source, pkt = buf + EXT_HDR_LEN; pkt_cmd_code = *(uint8_t *)pkt; len -= EXT_HDR_LEN; - if (len < 0) { - pr_err("diag: %s, Invalid length len: %d\n", __func__, len); - return; - } switch (pkt_cmd_code) { case LOG_CMD_CODE: diff --git a/drivers/gpu/msm/kgsl.c b/drivers/gpu/msm/kgsl.c index edd3890cf25c844ee7dd9ac0d728dd21e6d11bcc..fdfdb35fa9c22417da10f2cfb323ceec9893aedb 100644 --- a/drivers/gpu/msm/kgsl.c +++ b/drivers/gpu/msm/kgsl.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2008-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2008-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -2947,7 +2947,7 @@ long kgsl_ioctl_gpuobj_sync(struct kgsl_device_private *dev_priv, long ret = 0; bool full_flush = false; uint64_t size = 0; - int i, count = 0; + int i; void __user *ptr; if (param->count == 0 || param->count > 128) @@ -2959,8 +2959,8 @@ long kgsl_ioctl_gpuobj_sync(struct kgsl_device_private *dev_priv, entries = kzalloc(param->count * sizeof(*entries), GFP_KERNEL); if (entries == NULL) { - ret = -ENOMEM; - goto out; + kfree(objs); + return -ENOMEM; } ptr = to_user_ptr(param->objs); @@ -2977,36 +2977,32 @@ long kgsl_ioctl_gpuobj_sync(struct kgsl_device_private *dev_priv, if (entries[i] == NULL) continue; - count++; - if (!(objs[i].op & KGSL_GPUMEM_CACHE_RANGE)) size += entries[i]->memdesc.size; else if (objs[i].offset < entries[i]->memdesc.size) size += (entries[i]->memdesc.size - objs[i].offset); full_flush = check_full_flush(size, objs[i].op); - if (full_flush) - break; + if (full_flush) { + trace_kgsl_mem_sync_full_cache(i, size); + flush_cache_all(); + goto out; + } ptr += sizeof(*objs); } - if (full_flush) { - trace_kgsl_mem_sync_full_cache(count, size); - flush_cache_all(); - } else { - for (i = 0; !ret && i < param->count; i++) - if (entries[i]) - ret = _kgsl_gpumem_sync_cache(entries[i], - objs[i].offset, objs[i].length, - objs[i].op); - } + for (i = 0; !ret && i < param->count; i++) + if (entries[i]) + ret = _kgsl_gpumem_sync_cache(entries[i], + objs[i].offset, objs[i].length, + objs[i].op); +out: for (i = 0; i < param->count; i++) if (entries[i]) kgsl_mem_entry_put(entries[i]); -out: kfree(entries); kfree(objs); diff --git a/drivers/input/touchscreen/stm/ftm4_pdc.c b/drivers/input/touchscreen/stm/ftm4_pdc.c index a11bdd882248054997618e5a3a8a2ad6730392c0..66a1d91262475ab9f20f3494cffa54dcd352cd2a 100644 --- a/drivers/input/touchscreen/stm/ftm4_pdc.c +++ b/drivers/input/touchscreen/stm/ftm4_pdc.c @@ -181,8 +181,8 @@ static DEVICE_ATTR(cmd, S_IWUSR | S_IWGRP, NULL, store_cmd); static DEVICE_ATTR(cmd_status, S_IRUGO, show_cmd_status, NULL); static DEVICE_ATTR(cmd_result, S_IRUGO, show_cmd_result, NULL); static DEVICE_ATTR(cmd_list, S_IRUGO, cmd_list_show, NULL); -static DEVICE_ATTR(fw_upgrade, S_IWUSR | S_IWGRP, NULL, store_upgrade); -static DEVICE_ATTR(check_fw, S_IWUSR | S_IWGRP, NULL, store_check_fw); +static DEVICE_ATTR(fw_upgrade, S_IWUSR, NULL, store_upgrade); +static DEVICE_ATTR(check_fw, S_IWUSR, NULL, store_check_fw); static DEVICE_ATTR(version, S_IRUGO, show_version_info, NULL); static DEVICE_ATTR(vrmode, S_IRUSR | S_IRGRP | S_IWUSR | S_IWGRP, show_vrmode, store_vrmode); @@ -238,7 +238,7 @@ static ssize_t store_upgrade(struct device *dev, struct fts_ts_info *info = dev_get_drvdata(dev); int ret = 0; - if (strlcpy(&info->test_fwpath[0], buf, count) <= 0) { + if (strlcpy(info->test_fwpath, buf, sizeof(info->test_fwpath)) <= 0) { tsp_debug_err(&info->client->dev, "%s: invalid firmware name\n", __func__); return -EINVAL; } @@ -422,6 +422,12 @@ static ssize_t store_cmd(struct device *dev, struct device_attribute *devattr, return -EINVAL; } + if (count == 0) { + tsp_debug_err(&info->client->dev, + "%s: no argument provided\n", __func__); + return -EINVAL; + } + if (count > CMD_STR_LEN) { tsp_debug_err(&info->client->dev, "%s: overflow command length\n", __func__); diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp40.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp40.c index f5533fd9062ed13aff74c79eff6ade9a2fff3149..5b1dd9427fda1ceedb7b148c8a293b29b6ae7ed0 100644 --- a/drivers/media/platform/msm/camera_v2/isp/msm_isp40.c +++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp40.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2013-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -1103,8 +1103,10 @@ static int msm_vfe40_start_fetch_engine_multi_pass(struct vfe_device *vfe_dev, fe_cfg->stream_id); vfe_dev->fetch_engine_info.bufq_handle = bufq_handle; + mutex_lock(&vfe_dev->buf_mgr->lock); rc = vfe_dev->buf_mgr->ops->get_buf_by_index( vfe_dev->buf_mgr, bufq_handle, fe_cfg->buf_idx, &buf); + mutex_unlock(&vfe_dev->buf_mgr->lock); if (rc < 0 || !buf) { pr_err("%s: No fetch buffer rc= %d buf= %pK\n", __func__, rc, buf); diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp44.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp44.c index c85bf1655b8c8070c0cd44fa4619a6e36c6b356f..d40fe5e73984cb3c09fc0e91b5eda8ce6a2dc881 100644 --- a/drivers/media/platform/msm/camera_v2/isp/msm_isp44.c +++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp44.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2013-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -885,8 +885,11 @@ static int msm_vfe44_fetch_engine_start(struct vfe_device *vfe_dev, vfe_dev->buf_mgr, fe_cfg->session_id, fe_cfg->stream_id); vfe_dev->fetch_engine_info.bufq_handle = bufq_handle; + + mutex_lock(&vfe_dev->buf_mgr->lock); rc = vfe_dev->buf_mgr->ops->get_buf_by_index( vfe_dev->buf_mgr, bufq_handle, fe_cfg->buf_idx, &buf); + mutex_unlock(&vfe_dev->buf_mgr->lock); if (rc < 0) { pr_err("%s: No fetch buffer\n", __func__); return -EINVAL; diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp46.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp46.c index 72ce32940c296fd6155ef3052b0bf00cadd1779d..ebb6930e1d8d609de51a7bf93b61adf402fa17ed 100644 --- a/drivers/media/platform/msm/camera_v2/isp/msm_isp46.c +++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp46.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2013-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -827,8 +827,10 @@ static int msm_vfe46_start_fetch_engine(struct vfe_device *vfe_dev, fe_cfg->stream_id); vfe_dev->fetch_engine_info.bufq_handle = bufq_handle; + mutex_lock(&vfe_dev->buf_mgr->lock); rc = vfe_dev->buf_mgr->ops->get_buf_by_index( vfe_dev->buf_mgr, bufq_handle, fe_cfg->buf_idx, &buf); + mutex_unlock(&vfe_dev->buf_mgr->lock); if (rc < 0 || !buf) { pr_err("%s: No fetch buffer rc= %d buf= %pK\n", __func__, rc, buf); diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp47.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp47.c index 0e39f591fc9c3379c1ad34af9fd9bba215b59a9b..eb58fb18e2d686d760cd971c35139632bac2d11f 100644 --- a/drivers/media/platform/msm/camera_v2/isp/msm_isp47.c +++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp47.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2013-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -1135,8 +1135,10 @@ int msm_vfe47_start_fetch_engine_multi_pass(struct vfe_device *vfe_dev, fe_cfg->stream_id); vfe_dev->fetch_engine_info.bufq_handle = bufq_handle; + mutex_lock(&vfe_dev->buf_mgr->lock); rc = vfe_dev->buf_mgr->ops->get_buf_by_index( vfe_dev->buf_mgr, bufq_handle, fe_cfg->buf_idx, &buf); + mutex_unlock(&vfe_dev->buf_mgr->lock); if (rc < 0 || !buf) { pr_err("%s: No fetch buffer rc= %d buf= %pK\n", __func__, rc, buf); diff --git a/net/bluetooth/hidp/core.c b/net/bluetooth/hidp/core.c index f64de569175a51e1476b78e153c4134140cea74b..a295b5ec9d4ab71ed29997396665d0469625134d 100644 --- a/net/bluetooth/hidp/core.c +++ b/net/bluetooth/hidp/core.c @@ -431,8 +431,8 @@ static void hidp_del_timer(struct hidp_session *session) del_timer(&session->timer); } -static void hidp_process_report(struct hidp_session *session, - int type, const u8 *data, int len, int intr) +static void hidp_process_report(struct hidp_session *session, int type, + const u8 *data, unsigned int len, int intr) { if (len > HID_MAX_BUFFER_SIZE) len = HID_MAX_BUFFER_SIZE; diff --git a/sound/soc/codecs/wcd_cpe_core.c b/sound/soc/codecs/wcd_cpe_core.c index fa9902e4a800adad427f81f62fd7022f03581ebe..480eb495354399708ce0264453db5a947c95c48c 100644 --- a/sound/soc/codecs/wcd_cpe_core.c +++ b/sound/soc/codecs/wcd_cpe_core.c @@ -1945,6 +1945,7 @@ struct wcd_cpe_core *wcd_cpe_init(const char *img_fname, init_completion(&core->online_compl); init_waitqueue_head(&core->ssr_entry.offline_poll_wait); mutex_init(&core->ssr_lock); + mutex_init(&core->session_lock); core->cpe_users = 0; core->cpe_clk_ref = 0; @@ -3399,6 +3400,7 @@ static struct cpe_lsm_session *wcd_cpe_alloc_lsm_session( * If this is the first session to be allocated, * only then register the afe service. */ + WCD_CPE_GRAB_LOCK(&core->session_lock, "session_lock"); if (!wcd_cpe_lsm_session_active()) afe_register_service = true; @@ -3413,6 +3415,7 @@ static struct cpe_lsm_session *wcd_cpe_alloc_lsm_session( dev_err(core->dev, "%s: max allowed sessions already allocated\n", __func__); + WCD_CPE_REL_LOCK(&core->session_lock, "session_lock"); return NULL; } @@ -3421,6 +3424,7 @@ static struct cpe_lsm_session *wcd_cpe_alloc_lsm_session( dev_err(core->dev, "%s: Failed to enable cpe, err = %d\n", __func__, ret); + WCD_CPE_REL_LOCK(&core->session_lock, "session_lock"); return NULL; } @@ -3467,6 +3471,8 @@ static struct cpe_lsm_session *wcd_cpe_alloc_lsm_session( init_completion(&session->cmd_comp); lsm_sessions[session_id] = session; + + WCD_CPE_REL_LOCK(&core->session_lock, "session_lock"); return session; err_afe_mode_cmd: @@ -3481,6 +3487,7 @@ err_ret: err_session_alloc: wcd_cpe_vote(core, false); + WCD_CPE_REL_LOCK(&core->session_lock, "session_lock"); return NULL; } @@ -3630,9 +3637,11 @@ static int wcd_cpe_dealloc_lsm_session(void *core_handle, struct wcd_cpe_core *core = core_handle; int ret = 0; + WCD_CPE_GRAB_LOCK(&core->session_lock, "session_lock"); if (!session) { dev_err(core->dev, "%s: Invalid lsm session\n", __func__); + WCD_CPE_REL_LOCK(&core->session_lock, "session_lock"); return -EINVAL; } @@ -3643,6 +3652,7 @@ static int wcd_cpe_dealloc_lsm_session(void *core_handle, "%s: Wrong session id %d max allowed = %d\n", __func__, session->id, WCD_CPE_LSM_MAX_SESSIONS); + WCD_CPE_REL_LOCK(&core->session_lock, "session_lock"); return -EINVAL; } @@ -3663,6 +3673,7 @@ static int wcd_cpe_dealloc_lsm_session(void *core_handle, "%s: Failed to un-vote cpe, err = %d\n", __func__, ret); + WCD_CPE_REL_LOCK(&core->session_lock, "session_lock"); return ret; } diff --git a/sound/soc/codecs/wcd_cpe_core.h b/sound/soc/codecs/wcd_cpe_core.h index b09b03d2f81d80e8e36f27d925057c43edd47993..1ac39347119743a0246eb7ade0ce59a8b9de8c99 100644 --- a/sound/soc/codecs/wcd_cpe_core.h +++ b/sound/soc/codecs/wcd_cpe_core.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2013-2016, 2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -172,6 +172,9 @@ struct wcd_cpe_core { /* mutex to protect cpe ssr status variables */ struct mutex ssr_lock; + /* mutex to protect cpe session status variables */ + struct mutex session_lock; + /* Store the calibration data needed for cpe */ struct cal_type_data *cal_data[WCD_CPE_LSM_CAL_MAX]; diff --git a/sound/soc/codecs/wcd_cpe_services.c b/sound/soc/codecs/wcd_cpe_services.c index 582fddfa1096cd2adf8aaa4fca00b682b22343c6..58f02f1f35f5bfd181b35004acb4ede0b0310c05 100644 --- a/sound/soc/codecs/wcd_cpe_services.c +++ b/sound/soc/codecs/wcd_cpe_services.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2014-2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2014-2016, 2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -615,8 +615,10 @@ static enum cpe_svc_result cpe_deregister_generic(struct cpe_info *t_info, return CPE_SVC_INVALID_HANDLE; } + CPE_SVC_GRAB_LOCK(&cpe_d.cpe_svc_lock, "cpe_svc"); list_del(&(n->list)); kfree(reg_handle); + CPE_SVC_REL_LOCK(&cpe_d.cpe_svc_lock, "cpe_svc"); return CPE_SVC_SUCCESS; } diff --git a/sound/soc/msm/qdsp6v2/msm-compress-q6-v2.c b/sound/soc/msm/qdsp6v2/msm-compress-q6-v2.c index 216927b007458e17f52fda9f6fdd61de90b4af8f..566d18405df05bb2e95741659e00b7986a150062 100644 --- a/sound/soc/msm/qdsp6v2/msm-compress-q6-v2.c +++ b/sound/soc/msm/qdsp6v2/msm-compress-q6-v2.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -3604,6 +3604,7 @@ static int msm_compr_adsp_stream_cmd_put(struct snd_kcontrol *kcontrol, struct snd_compr_stream *cstream = NULL; struct msm_compr_audio *prtd; int ret = 0, param_length = 0; + uint64_t actual_payload_len = 0; if (fe_id >= MSM_FRONTEND_DAI_MAX) { pr_err("%s Received invalid fe_id %lu\n", @@ -3634,6 +3635,15 @@ static int msm_compr_adsp_stream_cmd_put(struct snd_kcontrol *kcontrol, memcpy(¶m_length, ucontrol->value.bytes.data, sizeof(param_length)); + + actual_payload_len = param_length + sizeof(param_length); + if (actual_payload_len > U32_MAX) { + pr_err("%s param length=0x%X exceeds limit", + __func__, param_length); + ret = -EINVAL; + goto done; + } + if ((param_length + sizeof(param_length)) >= sizeof(ucontrol->value.bytes.data)) { pr_err("%s param length=%d exceeds limit", diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.c b/sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.c index d0888ce9ed9f4f3694bdbac347efce1ad47c40c5..7f6dd520ce90e80e9ec85532f425eb84814309de 100644 --- a/sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.c +++ b/sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -1101,7 +1101,9 @@ static int msm_pcm_adsp_stream_cmd_put(struct snd_kcontrol *kcontrol, struct msm_plat_data *pdata = dev_get_drvdata(platform->dev); struct snd_pcm_substream *substream; struct msm_audio *prtd; - int ret = 0, param_length = 0; + int ret = 0; + uint32_t param_length = 0; + uint64_t actual_payload_len = 0; if (!pdata) { pr_err("%s pdata is NULL\n", __func__); @@ -1131,6 +1133,16 @@ static int msm_pcm_adsp_stream_cmd_put(struct snd_kcontrol *kcontrol, memcpy(¶m_length, ucontrol->value.bytes.data, sizeof(param_length)); + + actual_payload_len = param_length + sizeof(param_length); + + if (actual_payload_len > U32_MAX) { + pr_err("%s param length=0x%X exceeds limit", + __func__, param_length); + ret = -EINVAL; + goto done; + } + if ((param_length + sizeof(param_length)) >= sizeof(ucontrol->value.bytes.data)) { pr_err("%s param length=%d exceeds limit", diff --git a/sound/soc/msm/qdsp6v2/q6asm.c b/sound/soc/msm/qdsp6v2/q6asm.c index 129053e19cf5102a08d789779686f3762530a9c3..6426e0b365eb1d773bb197d9a32e70f261ad8a63 100644 --- a/sound/soc/msm/qdsp6v2/q6asm.c +++ b/sound/soc/msm/qdsp6v2/q6asm.c @@ -1099,7 +1099,9 @@ int q6asm_send_stream_cmd(struct audio_client *ac, uint32_t opcode, { char *asm_params = NULL; struct apr_hdr hdr; - int sz, rc; + int rc; + uint32_t sz = 0; + uint64_t actual_sz = 0; if (!param || !ac) { pr_err("%s: %s is NULL\n", __func__, @@ -1108,7 +1110,15 @@ int q6asm_send_stream_cmd(struct audio_client *ac, uint32_t opcode, goto done; } - sz = sizeof(struct apr_hdr) + params_length; + actual_sz = sizeof(struct apr_hdr) + params_length; + if (actual_sz > U32_MAX) { + pr_err("%s: payload size 0x%X exceeds limit\n", + __func__, params_length); + rc = -EINVAL; + goto done; + } + + sz = (uint32_t)actual_sz; asm_params = kzalloc(sz, GFP_KERNEL); if (!asm_params) { rc = -ENOMEM;