diff --git a/drivers/amba/bus.c b/drivers/amba/bus.c index 42086ad535c564d3357a1848bcad25ac034b08c9..35603b7f0e90fc0f60b144ff7b883ecc21614e31 100644 --- a/drivers/amba/bus.c +++ b/drivers/amba/bus.c @@ -68,11 +68,15 @@ static ssize_t driver_override_show(struct device *_dev, struct device_attribute *attr, char *buf) { struct amba_device *dev = to_amba_device(_dev); + ssize_t len; if (!dev->driver_override) return 0; - return sprintf(buf, "%s\n", dev->driver_override); + device_lock(_dev); + len = sprintf(buf, "%s\n", dev->driver_override); + device_unlock(_dev); + return len; } static ssize_t driver_override_store(struct device *_dev, @@ -80,7 +84,7 @@ static ssize_t driver_override_store(struct device *_dev, const char *buf, size_t count) { struct amba_device *dev = to_amba_device(_dev); - char *driver_override, *old = dev->driver_override, *cp; + char *driver_override, *old, *cp; /* We need to keep extra room for a newline */ if (count >= (PAGE_SIZE - 1)) @@ -94,12 +98,15 @@ static ssize_t driver_override_store(struct device *_dev, if (cp) *cp = '\0'; + device_lock(_dev); + old = dev->driver_override; if (strlen(driver_override)) { dev->driver_override = driver_override; } else { kfree(driver_override); dev->driver_override = NULL; } + device_unlock(_dev); kfree(old); diff --git a/drivers/char/adsprpc.c b/drivers/char/adsprpc.c index 2730299ee552c04d94b4054efc66a2afffbcc12a..b349130ffe6278f9666bc45bfc29fda386457681 100644 --- a/drivers/char/adsprpc.c +++ b/drivers/char/adsprpc.c @@ -1,5 +1,5 @@ /* - * 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 @@ -112,7 +112,7 @@ static inline uint64_t buf_page_offset(uint64_t buf) return offset; } -static inline int buf_num_pages(uint64_t buf, ssize_t len) +static inline int buf_num_pages(uint64_t buf, size_t len) { uint64_t start = buf_page_start(buf) >> PAGE_SHIFT; uint64_t end = (((uint64_t) buf + len - 1) & PAGE_MASK) >> PAGE_SHIFT; @@ -145,7 +145,7 @@ struct fastrpc_buf { struct fastrpc_file *fl; void *virt; uint64_t phys; - ssize_t size; + size_t size; }; struct fastrpc_ctx_lst; @@ -171,7 +171,7 @@ struct smq_invoke_ctx { unsigned *attrs; struct fastrpc_mmap **maps; struct fastrpc_buf *buf; - ssize_t used; + size_t used; struct fastrpc_file *fl; uint32_t sc; struct overlap *overs; @@ -260,9 +260,9 @@ struct fastrpc_mmap { struct dma_buf_attachment *attach; struct ion_handle *handle; uint64_t phys; - ssize_t size; + size_t size; uintptr_t va; - ssize_t len; + size_t len; int refs; uintptr_t raddr; int uncached; @@ -345,7 +345,7 @@ static inline int64_t getnstimediff(struct timespec *start) static void fastrpc_buf_free(struct fastrpc_buf *buf, int cache) { - struct fastrpc_file *fl = buf == 0 ? 0 : buf->fl; + struct fastrpc_file *fl = buf == NULL ? NULL : buf->fl; int vmid; if (!fl) @@ -380,7 +380,8 @@ static void fastrpc_buf_list_free(struct fastrpc_file *fl) struct fastrpc_buf *buf, *free; do { struct hlist_node *n; - free = 0; + + free = NULL; spin_lock(&fl->hlock); hlist_for_each_entry_safe(buf, n, &fl->bufs, hn) { hlist_del_init(&buf->hn); @@ -412,11 +413,14 @@ static void fastrpc_mmap_add(struct fastrpc_mmap *map) } static int fastrpc_mmap_find(struct fastrpc_file *fl, int fd, uintptr_t va, - ssize_t len, int mflags, struct fastrpc_mmap **ppmap) + size_t len, int mflags, struct fastrpc_mmap **ppmap) { struct fastrpc_apps *me = &gfa; - struct fastrpc_mmap *match = 0, *map; + struct fastrpc_mmap *match = NULL, *map = NULL; struct hlist_node *n; + + if ((va + len) < va) + return -EOVERFLOW; if (mflags == ADSP_MMAP_HEAP_ADDR || mflags == ADSP_MMAP_REMOTE_HEAP_ADDR) { spin_lock(&me->hlock); @@ -450,10 +454,10 @@ static int fastrpc_mmap_find(struct fastrpc_file *fl, int fd, uintptr_t va, return -ENOTTY; } -static int dma_alloc_memory(phys_addr_t *region_start, ssize_t size) +static int dma_alloc_memory(phys_addr_t *region_start, size_t size) { struct fastrpc_apps *me = &gfa; - void *vaddr = 0; + void *vaddr = NULL; DEFINE_DMA_ATTRS(attrs); if (me->dev == NULL) { @@ -473,9 +477,9 @@ static int dma_alloc_memory(phys_addr_t *region_start, ssize_t size) } static int fastrpc_mmap_remove(struct fastrpc_file *fl, uintptr_t va, - ssize_t len, struct fastrpc_mmap **ppmap) + size_t len, struct fastrpc_mmap **ppmap) { - struct fastrpc_mmap *match = 0, *map; + struct fastrpc_mmap *match = NULL, *map; struct hlist_node *n; struct fastrpc_apps *me = &gfa; @@ -593,14 +597,14 @@ static int fastrpc_session_alloc(struct fastrpc_channel_ctx *chan, int secure, struct fastrpc_session_ctx **session); static int fastrpc_mmap_create(struct fastrpc_file *fl, int fd, unsigned attr, - uintptr_t va, ssize_t len, int mflags, struct fastrpc_mmap **ppmap) + uintptr_t va, size_t len, int mflags, struct fastrpc_mmap **ppmap) { struct fastrpc_apps *me = &gfa; struct fastrpc_session_ctx *sess; struct fastrpc_apps *apps = fl->apps; int cid = fl->cid; struct fastrpc_channel_ctx *chan = &apps->channel[cid]; - struct fastrpc_mmap *map = 0; + struct fastrpc_mmap *map = NULL; struct dma_attrs attrs; phys_addr_t region_start = 0; unsigned long flags; @@ -621,13 +625,13 @@ static int fastrpc_mmap_create(struct fastrpc_file *fl, int fd, unsigned attr, if (mflags == ADSP_MMAP_HEAP_ADDR || mflags == ADSP_MMAP_REMOTE_HEAP_ADDR) { map->apps = me; - map->fl = 0; + map->fl = NULL; VERIFY(err, !dma_alloc_memory(®ion_start, len)); if (err) goto bail; map->phys = (uintptr_t)region_start; map->size = len; - map->va = map->phys; + map->va = (uintptr_t)map->phys; } else { VERIFY(err, !IS_ERR_OR_NULL(map->handle = ion_import_dma_buf(fl->apps->client, fd))); @@ -725,11 +729,11 @@ bail: return err; } -static int fastrpc_buf_alloc(struct fastrpc_file *fl, ssize_t size, +static int fastrpc_buf_alloc(struct fastrpc_file *fl, size_t size, struct fastrpc_buf **obuf) { int err = 0, vmid; - struct fastrpc_buf *buf = 0, *fr = 0; + struct fastrpc_buf *buf = NULL, *fr = NULL; struct hlist_node *n; VERIFY(err, size > 0); @@ -749,13 +753,13 @@ static int fastrpc_buf_alloc(struct fastrpc_file *fl, ssize_t size, *obuf = fr; return 0; } - buf = 0; - VERIFY(err, buf = kzalloc(sizeof(*buf), GFP_KERNEL)); + buf = NULL; + VERIFY(err, NULL != (buf = kzalloc(sizeof(*buf), GFP_KERNEL))); if (err) goto bail; INIT_HLIST_NODE(&buf->hn); buf->fl = fl; - buf->virt = 0; + buf->virt = NULL; buf->phys = 0; buf->size = size; buf->virt = dma_alloc_coherent(fl->sctx->smmu.dev, buf->size, @@ -797,7 +801,7 @@ static int context_restore_interrupted(struct fastrpc_file *fl, struct smq_invoke_ctx **po) { int err = 0; - struct smq_invoke_ctx *ctx = 0, *ictx = 0; + struct smq_invoke_ctx *ctx = NULL, *ictx = NULL; struct hlist_node *n; struct fastrpc_ioctl_invoke *invoke = &inv->inv; spin_lock(&fl->hlock); @@ -879,7 +883,8 @@ bail: #define K_COPY_FROM_USER(err, kernel, dst, src, size) \ do {\ if (!(kernel))\ - VERIFY(err, 0 == copy_from_user((dst), (src),\ + VERIFY(err, 0 == copy_from_user((dst),\ + (void const __user *)(src),\ (size)));\ else\ memmove((dst), (src), (size));\ @@ -888,8 +893,8 @@ bail: #define K_COPY_TO_USER(err, kernel, dst, src, size) \ do {\ if (!(kernel))\ - VERIFY(err, 0 == copy_to_user((dst), (src),\ - (size)));\ + VERIFY(err, 0 == copy_to_user((void __user *)(dst), \ + (src), (size)));\ else\ memmove((dst), (src), (size));\ } while (0) @@ -903,7 +908,7 @@ static int context_alloc(struct fastrpc_file *fl, uint32_t kernel, { int err = 0, bufs, ii, size = 0; struct fastrpc_apps *me = &gfa; - struct smq_invoke_ctx *ctx = 0; + struct smq_invoke_ctx *ctx = NULL; struct fastrpc_ctx_lst *clst = &fl->clst; struct fastrpc_ioctl_invoke *invoke = &invokefd->inv; @@ -914,7 +919,7 @@ static int context_alloc(struct fastrpc_file *fl, uint32_t kernel, sizeof(*ctx->overs) * (bufs) + sizeof(*ctx->overps) * (bufs); - VERIFY(err, ctx = kzalloc(sizeof(*ctx) + size, GFP_KERNEL)); + VERIFY(err, NULL != (ctx = kzalloc(sizeof(*ctx) + size, GFP_KERNEL))); if (err) goto bail; @@ -928,7 +933,7 @@ static int context_alloc(struct fastrpc_file *fl, uint32_t kernel, ctx->overs = (struct overlap *)(&ctx->attrs[bufs]); ctx->overps = (struct overlap **)(&ctx->overs[bufs]); - K_COPY_FROM_USER(err, kernel, ctx->lpra, invoke->pra, + K_COPY_FROM_USER(err, kernel, (void *)ctx->lpra, invoke->pra, bufs * sizeof(*ctx->lpra)); if (err) goto bail; @@ -1065,10 +1070,10 @@ static void context_list_ctor(struct fastrpc_ctx_lst *me) static void fastrpc_context_list_dtor(struct fastrpc_file *fl) { struct fastrpc_ctx_lst *clst = &fl->clst; - struct smq_invoke_ctx *ictx = 0, *ctxfree; + struct smq_invoke_ctx *ictx = NULL, *ctxfree; struct hlist_node *n; do { - ctxfree = 0; + ctxfree = NULL; spin_lock(&fl->hlock); hlist_for_each_entry_safe(ictx, n, &clst->interrupted, hn) { hlist_del_init(&ictx->hn); @@ -1080,7 +1085,7 @@ static void fastrpc_context_list_dtor(struct fastrpc_file *fl) context_free(ctxfree); } while (ctxfree); do { - ctxfree = 0; + ctxfree = NULL; spin_lock(&fl->hlock); hlist_for_each_entry_safe(ictx, n, &clst->pending, hn) { hlist_del_init(&ictx->hn); @@ -1099,7 +1104,7 @@ static void fastrpc_file_list_dtor(struct fastrpc_apps *me) struct fastrpc_file *fl, *free; struct hlist_node *n; do { - free = 0; + free = NULL; spin_lock(&me->hlock); hlist_for_each_entry_safe(fl, n, &me->drivers, hn) { hlist_del_init(&fl->hn); @@ -1123,20 +1128,20 @@ static int get_args(uint32_t kernel, struct smq_invoke_ctx *ctx) int outbufs = REMOTE_SCALARS_OUTBUFS(sc); int bufs = inbufs + outbufs; uintptr_t args; - ssize_t rlen = 0, copylen = 0, metalen = 0; + size_t rlen = 0, copylen = 0, metalen = 0; int i, inh, oix; int err = 0; int mflags = 0; /* calculate size of the metadata */ - rpra = 0; + rpra = NULL; list = smq_invoke_buf_start(rpra, sc); pages = smq_phy_page_start(sc, list); ipage = pages; for (i = 0; i < bufs; ++i) { uintptr_t buf = (uintptr_t)lpra[i].buf.pv; - ssize_t len = lpra[i].buf.len; + size_t len = lpra[i].buf.len; if (ctx->fds[i] && (ctx->fds[i] != -1)) fastrpc_mmap_create(ctx->fl, ctx->fds[i], @@ -1144,12 +1149,12 @@ static int get_args(uint32_t kernel, struct smq_invoke_ctx *ctx) mflags, &ctx->maps[i]); ipage += 1; } - metalen = copylen = (ssize_t)&ipage[0]; + metalen = copylen = (size_t)&ipage[0]; /* calculate len requreed for copying */ for (oix = 0; oix < inbufs + outbufs; ++oix) { int i = ctx->overps[oix]->raix; uintptr_t mstart, mend; - ssize_t len = lpra[i].buf.len; + size_t len = lpra[i].buf.len; if (!len) continue; if (ctx->maps[i]) @@ -1182,7 +1187,7 @@ static int get_args(uint32_t kernel, struct smq_invoke_ctx *ctx) ipage = pages; args = (uintptr_t)ctx->buf->virt + metalen; for (i = 0; i < bufs; ++i) { - ssize_t len = lpra[i].buf.len; + size_t len = lpra[i].buf.len; list[i].num = 0; list[i].pgidx = 0; if (!len) @@ -1196,7 +1201,7 @@ static int get_args(uint32_t kernel, struct smq_invoke_ctx *ctx) for (i = 0; i < inbufs + outbufs; ++i) { struct fastrpc_mmap *map = ctx->maps[i]; uint64_t buf = ptr_to_uint64(lpra[i].buf.pv); - ssize_t len = lpra[i].buf.len; + size_t len = lpra[i].buf.len; rpra[i].buf.pv = 0; rpra[i].buf.len = len; if (!len) @@ -1204,7 +1209,7 @@ static int get_args(uint32_t kernel, struct smq_invoke_ctx *ctx) if (map) { struct vm_area_struct *vma; uintptr_t offset; - int num = buf_num_pages(buf, len); + uint64_t num = buf_num_pages(buf, len); int idx = list[i].pgidx; if (map->attr & FASTRPC_ATTR_NOVA) { @@ -1236,9 +1241,9 @@ static int get_args(uint32_t kernel, struct smq_invoke_ctx *ctx) for (oix = 0; oix < inbufs + outbufs; ++oix) { int i = ctx->overps[oix]->raix; struct fastrpc_mmap *map = ctx->maps[i]; - ssize_t mlen; + size_t mlen; uint64_t buf; - ssize_t len = lpra[i].buf.len; + size_t len = lpra[i].buf.len; if (!len) continue; if (map) @@ -1325,7 +1330,7 @@ static int put_args(uint32_t kernel, struct smq_invoke_ctx *ctx, goto bail; } else { fastrpc_mmap_free(ctx->maps[i]); - ctx->maps[i] = 0; + ctx->maps[i] = NULL; } } size = sizeof(*rpra) * REMOTE_SCALARS_OUTHANDLES(sc); @@ -1425,7 +1430,7 @@ static int fastrpc_invoke_send(struct smq_invoke_ctx *ctx, struct fastrpc_channel_ctx *channel_ctx = &fl->apps->channel[fl->cid]; int err = 0; - VERIFY(err, 0 != channel_ctx->chan); + VERIFY(err, NULL != channel_ctx->chan); if (err) goto bail; msg->pid = current->tgid; @@ -1475,14 +1480,14 @@ static int fastrpc_internal_invoke(struct fastrpc_file *fl, uint32_t mode, uint32_t kernel, struct fastrpc_ioctl_invoke_attrs *inv) { - struct smq_invoke_ctx *ctx = 0; + struct smq_invoke_ctx *ctx = NULL; struct fastrpc_ioctl_invoke *invoke = &inv->inv; int cid = fl->cid; int interrupted = 0; int err = 0; - struct timespec invoket; + struct timespec invoket = {0}; - VERIFY(err, fl->sctx); + VERIFY(err, fl->sctx != NULL); if (err) goto bail; VERIFY(err, fl->cid >= 0 && fl->cid < NUM_CHANNELS); @@ -1577,7 +1582,7 @@ static int fastrpc_init_process(struct fastrpc_file *fl, struct fastrpc_ioctl_invoke_attrs ioctl; struct fastrpc_ioctl_init *init = &uproc->init; struct smq_phy_page pages[1]; - struct fastrpc_mmap *file = 0, *mem = 0; + struct fastrpc_mmap *file = NULL, *mem = NULL; char *proc_name = NULL; int srcVM[1] = {VMID_HLOS}; int destVM[1] = {VMID_ADSP_Q6}; @@ -1595,8 +1600,8 @@ static int fastrpc_init_process(struct fastrpc_file *fl, ioctl.inv.handle = 1; ioctl.inv.sc = REMOTE_SCALARS_MAKE(0, 1, 0); ioctl.inv.pra = ra; - ioctl.fds = 0; - ioctl.attrs = 0; + ioctl.fds = NULL; + ioctl.attrs = NULL; fl->pd = 0; VERIFY(err, !(err = fastrpc_internal_invoke(fl, FASTRPC_MODE_PARALLEL, 1, &ioctl))); @@ -1608,9 +1613,9 @@ static int fastrpc_init_process(struct fastrpc_file *fl, int mflags = 0; struct { int pgid; - int namelen; - int filelen; - int pageslen; + unsigned int namelen; + unsigned int filelen; + unsigned int pageslen; int attrs; int siglen; } inbuf; @@ -1671,7 +1676,7 @@ static int fastrpc_init_process(struct fastrpc_file *fl, ioctl.inv.sc = REMOTE_SCALARS_MAKE(7, 6, 0); ioctl.inv.pra = ra; ioctl.fds = fds; - ioctl.attrs = 0; + ioctl.attrs = NULL; VERIFY(err, !(err = fastrpc_internal_invoke(fl, FASTRPC_MODE_PARALLEL, 1, &ioctl))); if (err) @@ -1679,21 +1684,23 @@ static int fastrpc_init_process(struct fastrpc_file *fl, } else if (init->flags == FASTRPC_INIT_CREATE_STATIC) { remote_arg_t ra[3]; uint64_t phys = 0; - ssize_t size = 0; + size_t size = 0; int fds[3]; struct { int pgid; - int namelen; - int pageslen; + unsigned int namelen; + unsigned int pageslen; } inbuf; if (!init->filelen) goto bail; - VERIFY(err, proc_name = kzalloc(init->filelen, GFP_KERNEL)); + + proc_name = kzalloc(init->filelen, GFP_KERNEL); + VERIFY(err, !IS_ERR_OR_NULL(proc_name)); if (err) goto bail; - VERIFY(err, 0 == copy_from_user(proc_name, - (unsigned char *)init->file, init->filelen)); + VERIFY(err, 0 == copy_from_user((void *)proc_name, + (void __user *)init->file, init->filelen)); if (err) goto bail; inbuf.pgid = current->tgid; @@ -1738,8 +1745,8 @@ static int fastrpc_init_process(struct fastrpc_file *fl, ioctl.inv.sc = REMOTE_SCALARS_MAKE(8, 3, 0); ioctl.inv.pra = ra; - ioctl.fds = 0; - ioctl.attrs = 0; + ioctl.fds = NULL; + ioctl.attrs = NULL; VERIFY(err, !(err = fastrpc_internal_invoke(fl, FASTRPC_MODE_PARALLEL, 1, &ioctl))); if (err) @@ -1772,7 +1779,7 @@ static int fastrpc_release_current_dsp_process(struct fastrpc_file *fl) VERIFY(err, fl->cid >= 0 && fl->cid < NUM_CHANNELS); if (err) goto bail; - VERIFY(err, fl->apps->channel[fl->cid].chan != 0); + VERIFY(err, fl->apps->channel[fl->cid].chan != NULL); if (err) goto bail; tgid = fl->tgid; @@ -1781,8 +1788,8 @@ static int fastrpc_release_current_dsp_process(struct fastrpc_file *fl) ioctl.inv.handle = 1; ioctl.inv.sc = REMOTE_SCALARS_MAKE(1, 1, 0); ioctl.inv.pra = ra; - ioctl.fds = 0; - ioctl.attrs = 0; + ioctl.fds = NULL; + ioctl.attrs = NULL; VERIFY(err, 0 == (err = fastrpc_internal_invoke(fl, FASTRPC_MODE_PARALLEL, 1, &ioctl))); bail: @@ -1827,8 +1834,8 @@ static int fastrpc_mmap_on_dsp(struct fastrpc_file *fl, uint32_t flags, else ioctl.inv.sc = REMOTE_SCALARS_MAKE(2, 2, 1); ioctl.inv.pra = ra; - ioctl.fds = 0; - ioctl.attrs = 0; + ioctl.fds = NULL; + ioctl.attrs = NULL; VERIFY(err, 0 == (err = fastrpc_internal_invoke(fl, FASTRPC_MODE_PARALLEL, 1, &ioctl))); map->raddr = (uintptr_t)routargs.vaddrout; @@ -1881,8 +1888,8 @@ static int fastrpc_munmap_on_dsp_rh(struct fastrpc_file *fl, ioctl.inv.handle = 1; ioctl.inv.sc = REMOTE_SCALARS_MAKE(7, 0, 1); ioctl.inv.pra = ra; - ioctl.fds = 0; - ioctl.attrs = 0; + ioctl.fds = NULL; + ioctl.attrs = NULL; if (fl == NULL) goto bail; @@ -1917,7 +1924,7 @@ static int fastrpc_munmap_on_dsp(struct fastrpc_file *fl, struct { int pid; uintptr_t vaddrout; - ssize_t size; + size_t size; } inargs; inargs.pid = current->tgid; @@ -1932,8 +1939,8 @@ static int fastrpc_munmap_on_dsp(struct fastrpc_file *fl, else ioctl.inv.sc = REMOTE_SCALARS_MAKE(3, 1, 0); ioctl.inv.pra = ra; - ioctl.fds = 0; - ioctl.attrs = 0; + ioctl.fds = NULL; + ioctl.attrs = NULL; VERIFY(err, 0 == (err = fastrpc_internal_invoke(fl, FASTRPC_MODE_PARALLEL, 1, &ioctl))); if (err) @@ -1950,13 +1957,13 @@ bail: static int fastrpc_mmap_remove_ssr(struct fastrpc_file *fl) { - struct fastrpc_mmap *match = 0, *map = NULL; + struct fastrpc_mmap *match = NULL, *map = NULL; struct hlist_node *n = NULL; int err = 0, ret = 0; struct fastrpc_apps *me = &gfa; struct ramdump_segment *ramdump_segments_rh = NULL; do { - match = 0; + match = NULL; spin_lock(&me->hlock); hlist_for_each_entry_safe(map, n, &me->maps, hn) { match = map; @@ -1994,7 +2001,7 @@ bail: } static int fastrpc_mmap_remove(struct fastrpc_file *fl, uintptr_t va, - ssize_t len, struct fastrpc_mmap **ppmap); + size_t len, struct fastrpc_mmap **ppmap); static void fastrpc_mmap_add(struct fastrpc_mmap *map); @@ -2002,7 +2009,7 @@ static int fastrpc_internal_munmap(struct fastrpc_file *fl, struct fastrpc_ioctl_munmap *ud) { int err = 0; - struct fastrpc_mmap *map = 0; + struct fastrpc_mmap *map = NULL; mutex_lock(&fl->map_mutex); VERIFY(err, !fastrpc_mmap_remove(fl, ud->vaddrout, ud->size, &map)); @@ -2023,7 +2030,7 @@ static int fastrpc_internal_mmap(struct fastrpc_file *fl, struct fastrpc_ioctl_mmap *ud) { - struct fastrpc_mmap *map = 0; + struct fastrpc_mmap *map = NULL; int err = 0; mutex_lock(&fl->map_mutex); @@ -2057,9 +2064,9 @@ static void fastrpc_channel_close(struct kref *kref) ctx = container_of(kref, struct fastrpc_channel_ctx, kref); cid = ctx - &gcinfo[0]; fastrpc_glink_close(ctx->chan, cid); - ctx->chan = 0; + ctx->chan = NULL; glink_unregister_link_state_cb(ctx->link.link_notify_handle); - ctx->link.link_notify_handle = 0; + ctx->link.link_notify_handle = NULL; mutex_unlock(&me->smd_mutex); pr_info("'closed /dev/%s c %d %d'\n", gcinfo[cid].name, MAJOR(me->dev_no), cid); @@ -2098,19 +2105,20 @@ static int fastrpc_session_alloc_locked(struct fastrpc_channel_ctx *chan, return err; } -bool fastrpc_glink_notify_rx_intent_req(void *h, const void *priv, size_t size) +static bool fastrpc_glink_notify_rx_intent_req(void *h, const void *priv, + size_t size) { if (glink_queue_rx_intent(h, NULL, size)) return false; return true; } -void fastrpc_glink_notify_tx_done(void *handle, const void *priv, +static void fastrpc_glink_notify_tx_done(void *handle, const void *priv, const void *pkt_priv, const void *ptr) { } -void fastrpc_glink_notify_rx(void *handle, const void *priv, +static 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; @@ -2143,7 +2151,8 @@ bail: glink_rx_done(handle, ptr, true); } -void fastrpc_glink_notify_state(void *handle, const void *priv, unsigned event) +static void fastrpc_glink_notify_state(void *handle, const void *priv, + unsigned event) { struct fastrpc_apps *me = &gfa; int cid = (int)(uintptr_t)priv; @@ -2199,7 +2208,7 @@ static void fastrpc_session_free(struct fastrpc_channel_ctx *chan, static int fastrpc_file_free(struct fastrpc_file *fl) { struct hlist_node *n; - struct fastrpc_mmap *map = 0; + struct fastrpc_mmap *map = NULL; int cid; if (!fl) @@ -2365,9 +2374,9 @@ static ssize_t fastrpc_debugfs_read(struct file *filp, char __user *buffer, { struct fastrpc_file *fl = filp->private_data; struct hlist_node *n; - struct fastrpc_buf *buf = 0; - struct fastrpc_mmap *map = 0; - struct smq_invoke_ctx *ictx = 0; + struct fastrpc_buf *buf = NULL; + struct fastrpc_mmap *map = NULL; + struct smq_invoke_ctx *ictx = NULL; struct fastrpc_channel_ctx *chan; struct fastrpc_session_ctx *sess; unsigned int len = 0; @@ -2491,7 +2500,7 @@ static int fastrpc_channel_open(struct fastrpc_file *fl) goto bail; fl->ssrcount = me->channel[cid].ssrcount; if ((kref_get_unless_zero(&me->channel[cid].kref) == 0) || - (me->channel[cid].chan == 0)) { + (me->channel[cid].chan == NULL)) { fastrpc_glink_register(cid, me); VERIFY(err, 0 == fastrpc_glink_open(cid)); if (err) @@ -2501,7 +2510,7 @@ static int fastrpc_channel_open(struct fastrpc_file *fl) wait_for_completion_timeout(&me->channel[cid].workport, RPC_TIMEOUT)); if (err) { - me->channel[cid].chan = 0; + me->channel[cid].chan = NULL; goto bail; } kref_init(&me->channel[cid].kref); @@ -2528,10 +2537,10 @@ static int fastrpc_device_open(struct inode *inode, struct file *filp) { int err = 0; struct dentry *debugfs_file; - struct fastrpc_file *fl = 0; + struct fastrpc_file *fl = NULL; struct fastrpc_apps *me = &gfa; - VERIFY(err, fl = kzalloc(sizeof(*fl), GFP_KERNEL)); + VERIFY(err, NULL != (fl = kzalloc(sizeof(*fl), GFP_KERNEL))); if (err) return err; debugfs_file = debugfs_create_file(current->comm, 0644, debugfs_root, @@ -2561,7 +2570,7 @@ static int fastrpc_get_info(struct fastrpc_file *fl, uint32_t *info) int err = 0; uint32_t cid; - VERIFY(err, fl != 0); + VERIFY(err, fl != NULL); if (err) goto bail; if (fl->cid == -1) { @@ -2596,8 +2605,8 @@ static long fastrpc_device_ioctl(struct file *file, unsigned int ioctl_num, int size = 0, err = 0; uint32_t info; - p.inv.fds = 0; - p.inv.attrs = 0; + p.inv.fds = NULL; + p.inv.attrs = NULL; switch (ioctl_num) { case FASTRPC_IOCTL_INVOKE: @@ -2609,7 +2618,7 @@ static long fastrpc_device_ioctl(struct file *file, unsigned int ioctl_num, case FASTRPC_IOCTL_INVOKE_ATTRS: if (!size) size = sizeof(struct fastrpc_ioctl_invoke_attrs); - VERIFY(err, 0 == copy_from_user(&p.inv, param, size)); + K_COPY_FROM_USER(err, 0, &p.inv, param, size); if (err) goto bail; VERIFY(err, 0 == (err = fastrpc_internal_invoke(fl, fl->mode, @@ -2618,20 +2627,20 @@ static long fastrpc_device_ioctl(struct file *file, unsigned int ioctl_num, goto bail; break; case FASTRPC_IOCTL_MMAP: - VERIFY(err, 0 == copy_from_user(&p.mmap, param, - sizeof(p.mmap))); + K_COPY_FROM_USER(err, 0, &p.mmap, param, + sizeof(p.mmap)); if (err) goto bail; VERIFY(err, 0 == (err = fastrpc_internal_mmap(fl, &p.mmap))); if (err) goto bail; - VERIFY(err, 0 == copy_to_user(param, &p.mmap, sizeof(p.mmap))); + K_COPY_TO_USER(err, 0, param, &p.mmap, sizeof(p.mmap)); if (err) goto bail; break; case FASTRPC_IOCTL_MUNMAP: - VERIFY(err, 0 == copy_from_user(&p.munmap, param, - sizeof(p.munmap))); + K_COPY_FROM_USER(err, 0, &p.munmap, param, + sizeof(p.munmap)); if (err) goto bail; VERIFY(err, 0 == (err = fastrpc_internal_munmap(fl, @@ -2654,35 +2663,35 @@ static long fastrpc_device_ioctl(struct file *file, unsigned int ioctl_num, } break; case FASTRPC_IOCTL_GETPERF: - VERIFY(err, 0 == copy_from_user(&p.perf, - param, sizeof(p.perf))); + K_COPY_FROM_USER(err, 0, &p.perf, + param, sizeof(p.perf)); if (err) goto bail; p.perf.numkeys = sizeof(struct fastrpc_perf)/sizeof(int64_t); if (p.perf.keys) { char *keys = PERF_KEYS; - VERIFY(err, 0 == copy_to_user((char *)p.perf.keys, - keys, strlen(keys)+1)); + K_COPY_TO_USER(err, 0, (void *)p.perf.keys, + keys, strlen(keys)+1); if (err) goto bail; } if (p.perf.data) { - VERIFY(err, 0 == copy_to_user((int64_t *)p.perf.data, - &fl->perf, sizeof(fl->perf))); + K_COPY_TO_USER(err, 0, (void *)p.perf.data, + &fl->perf, sizeof(fl->perf)); } - VERIFY(err, 0 == copy_to_user(param, &p.perf, sizeof(p.perf))); + K_COPY_TO_USER(err, 0, param, &p.perf, sizeof(p.perf)); if (err) goto bail; break; case FASTRPC_IOCTL_GETINFO: - VERIFY(err, 0 == copy_from_user(&info, param, sizeof(info))); + K_COPY_FROM_USER(err, 0, &info, param, sizeof(info)); if (err) goto bail; VERIFY(err, 0 == (err = fastrpc_get_info(fl, &info))); if (err) goto bail; - VERIFY(err, 0 == copy_to_user(param, &info, sizeof(info))); + K_COPY_TO_USER(err, 0, param, &info, sizeof(info)); if (err) goto bail; break; @@ -2694,14 +2703,14 @@ static long fastrpc_device_ioctl(struct file *file, unsigned int ioctl_num, case FASTRPC_IOCTL_INIT_ATTRS: if (!size) size = sizeof(struct fastrpc_ioctl_init_attrs); - VERIFY(err, 0 == copy_from_user(&p.init, param, size)); + K_COPY_FROM_USER(err, 0, &p.init, param, size); if (err) goto bail; VERIFY(err, p.init.init.filelen >= 0 && p.init.init.memlen >= 0); if (err) goto bail; - VERIFY(err, 0 == fastrpc_init_process(fl, &p.init)); + VERIFY(err, 0 == (err = fastrpc_init_process(fl, &p.init))); if (err) goto bail; break; @@ -2732,7 +2741,7 @@ static int fastrpc_restart_notifier_cb(struct notifier_block *nb, ctx->issubsystemup = 0; if (ctx->chan) { fastrpc_glink_close(ctx->chan, cid); - ctx->chan = 0; + ctx->chan = NULL; pr_info("'restart notifier: closed /dev/%s c %d %d'\n", gcinfo[cid].name, MAJOR(me->dev_no), cid); } @@ -2792,7 +2801,8 @@ static int fastrpc_cb_probe(struct device *dev) int err = 0, i; int secure_vmid = VMID_CP_PIXEL; - VERIFY(err, 0 != (name = of_get_property(dev->of_node, "label", NULL))); + VERIFY(err, NULL != (name = of_get_property(dev->of_node, + "label", NULL))); if (err) goto bail; for (i = 0; i < NUM_CHANNELS; i++) { @@ -2853,8 +2863,8 @@ static int fastrpc_cb_legacy_probe(struct device *dev) struct fastrpc_channel_ctx *chan; struct fastrpc_session_ctx *first_sess, *sess; const char *name; - unsigned int *range = 0, range_size = 0; - unsigned int *sids = 0, sids_size = 0; + unsigned int *range = NULL, range_size = 0; + unsigned int *sids = NULL, sids_size = 0; int err = 0, ret = 0, i; VERIFY(err, 0 != (domains_child_node = of_get_child_by_name( @@ -2975,17 +2985,17 @@ static void fastrpc_deinit(void) if (chan->chan) { kref_put_mutex(&chan->kref, fastrpc_channel_close, &me->smd_mutex); - chan->chan = 0; + chan->chan = NULL; } for (j = 0; j < NUM_SESSIONS; j++) { struct fastrpc_session_ctx *sess = &chan->session[j]; if (sess->smmu.dev) { arm_iommu_detach_device(sess->smmu.dev); - sess->smmu.dev = 0; + sess->smmu.dev = NULL; } if (sess->smmu.mapping) { arm_iommu_release_mapping(sess->smmu.mapping); - sess->smmu.mapping = 0; + sess->smmu.mapping = NULL; } } } @@ -3003,7 +3013,7 @@ static struct platform_driver fastrpc_driver = { static int __init fastrpc_device_init(void) { struct fastrpc_apps *me = &gfa; - struct device *dev = 0; + struct device *dev = NULL; int err = 0, i; memset(me, 0, sizeof(*me)); @@ -3027,7 +3037,7 @@ static int __init fastrpc_device_init(void) VERIFY(err, !IS_ERR(me->class)); if (err) goto class_create_bail; - me->compat = (NULL == fops.compat_ioctl) ? 0 : 1; + me->compat = (fops.compat_ioctl == NULL) ? 0 : 1; dev = device_create(me->class, NULL, MKDEV(MAJOR(me->dev_no), 0), NULL, gcinfo[0].name); @@ -3040,7 +3050,7 @@ static int __init fastrpc_device_init(void) me->channel[i].prevssrcount = 0; me->channel[i].issubsystemup = 1; me->channel[i].ramdumpenabled = 0; - me->channel[i].remoteheap_ramdump_dev = 0; + me->channel[i].remoteheap_ramdump_dev = NULL; me->channel[i].nb.notifier_call = fastrpc_restart_notifier_cb; me->channel[i].handle = subsys_notif_register_notifier( gcinfo[i].subsys, diff --git a/drivers/char/adsprpc_compat.c b/drivers/char/adsprpc_compat.c index fcd6d11426186e7d09b43123f32e65468a644950..ade36a5d6d543c969d583c122c13425c978b6b61 100644 --- a/drivers/char/adsprpc_compat.c +++ b/drivers/char/adsprpc_compat.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2017, The Linux Foundation. All rights reserved. + * Copyright (c) 2014-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 @@ -39,7 +39,7 @@ struct compat_remote_buf { compat_uptr_t pv; /* buffer pointer */ - compat_ssize_t len; /* length of buffer */ + compat_size_t len; /* length of buffer */ }; union compat_remote_arg { @@ -68,13 +68,13 @@ struct compat_fastrpc_ioctl_mmap { compat_int_t fd; /* ion fd */ compat_uint_t flags; /* flags for dsp to map with */ compat_uptr_t vaddrin; /* optional virtual address */ - compat_ssize_t size; /* size */ + compat_size_t size; /* size */ compat_uptr_t vaddrout; /* dsps virtual address */ }; struct compat_fastrpc_ioctl_munmap { compat_uptr_t vaddrout; /* address to unmap */ - compat_ssize_t size; /* size */ + compat_size_t size; /* size */ }; struct compat_fastrpc_ioctl_init { @@ -105,7 +105,7 @@ static int compat_get_fastrpc_ioctl_invoke( unsigned int cmd) { compat_uint_t u, sc; - compat_ssize_t s; + compat_size_t s; compat_uptr_t p; struct fastrpc_ioctl_invoke_attrs *inv; union compat_remote_arg *pra32; @@ -193,7 +193,7 @@ static int compat_get_fastrpc_ioctl_mmap( { compat_uint_t u; compat_int_t i; - compat_ssize_t s; + compat_size_t s; compat_uptr_t p; int err; @@ -227,7 +227,7 @@ static int compat_get_fastrpc_ioctl_munmap( struct fastrpc_ioctl_munmap __user *unmap) { compat_uptr_t p; - compat_ssize_t s; + compat_size_t s; int err; err = get_user(p, &unmap32->vaddrout); diff --git a/drivers/char/adsprpc_shared.h b/drivers/char/adsprpc_shared.h index 2a66b11bf179b3e14afc7a82249f2134e55f9b00..43cf9acccc349b1c4fcb5b728315b8e1ef8693da 100644 --- a/drivers/char/adsprpc_shared.h +++ b/drivers/char/adsprpc_shared.h @@ -1,5 +1,5 @@ /* - * 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 @@ -125,7 +125,7 @@ union remote_arg64 { struct remote_buf { void *pv; /* buffer pointer */ - ssize_t len; /* length of buffer */ + size_t len; /* length of buffer */ }; union remote_arg { @@ -152,11 +152,11 @@ struct fastrpc_ioctl_invoke_attrs { struct fastrpc_ioctl_init { uint32_t flags; /* one of FASTRPC_INIT_* macros */ - uintptr_t __user file; /* pointer to elf file */ - int32_t filelen; /* elf file length */ + uintptr_t file; /* pointer to elf file */ + uint32_t filelen; /* elf file length */ int32_t filefd; /* ION fd for the file */ - uintptr_t __user mem; /* mem for the PD */ - int32_t memlen; /* mem length */ + uintptr_t mem; /* mem for the PD */ + uint32_t memlen; /* mem length */ int32_t memfd; /* ION fd for the mem */ }; @@ -168,21 +168,21 @@ struct fastrpc_ioctl_init_attrs { struct fastrpc_ioctl_munmap { uintptr_t vaddrout; /* address to unmap */ - ssize_t size; /* size */ + size_t size; /* size */ }; struct fastrpc_ioctl_mmap { int fd; /* ion fd */ uint32_t flags; /* flags for dsp to map with */ - uintptr_t __user *vaddrin; /* optional virtual address */ - ssize_t size; /* size */ + uintptr_t vaddrin; /* optional virtual address */ + size_t size; /* size */ uintptr_t vaddrout; /* dsps virtual address */ }; struct fastrpc_ioctl_perf { /* kernel performance data */ - uintptr_t __user data; + uintptr_t data; uint32_t numkeys; - uintptr_t __user keys; + uintptr_t keys; }; struct smq_null_invoke { @@ -220,14 +220,15 @@ struct smq_invoke_rsp { static inline struct smq_invoke_buf *smq_invoke_buf_start(remote_arg64_t *pra, uint32_t sc) { - int len = REMOTE_SCALARS_LENGTH(sc); + unsigned int len = REMOTE_SCALARS_LENGTH(sc); + return (struct smq_invoke_buf *)(&pra[len]); } static inline struct smq_phy_page *smq_phy_page_start(uint32_t sc, struct smq_invoke_buf *buf) { - int nTotal = REMOTE_SCALARS_INBUFS(sc) + REMOTE_SCALARS_OUTBUFS(sc); + uint32_t nTotal = REMOTE_SCALARS_INBUFS(sc)+REMOTE_SCALARS_OUTBUFS(sc); return (struct smq_phy_page *)(&buf[nTotal]); } diff --git a/drivers/cpuidle/lpm-levels-of.c b/drivers/cpuidle/lpm-levels-of.c index ffbfd1c11af9e93c165cdffb0562598c76550115..6ff271438fd3236990758c571df34593db4e43b3 100644 --- a/drivers/cpuidle/lpm-levels-of.c +++ b/drivers/cpuidle/lpm-levels-of.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 @@ -848,14 +848,12 @@ failed: void free_cluster_node(struct lpm_cluster *cluster) { - struct list_head *list; int i; + struct lpm_cluster *cl, *m; - list_for_each(list, &cluster->child) { - struct lpm_cluster *n; - n = list_entry(list, typeof(*n), list); - list_del(list); - free_cluster_node(n); + list_for_each_entry_safe(cl, m, &cluster->child, list) { + list_del(&cl->list); + free_cluster_node(cl); }; if (cluster->cpu) { diff --git a/drivers/media/platform/msm/camera_v2/sensor/ois/msm_ois.c b/drivers/media/platform/msm/camera_v2/sensor/ois/msm_ois.c index 3ee1412bbcf4248bca8f2519224433a94f945d1f..9b4bed8978dba8df3596c7aa63409f1264b0a2e2 100644 --- a/drivers/media/platform/msm/camera_v2/sensor/ois/msm_ois.c +++ b/drivers/media/platform/msm/camera_v2/sensor/ois/msm_ois.c @@ -1158,6 +1158,10 @@ static long msm_ois_subdev_do_ioctl( parg = &ois_data; break; } + break; + case VIDIOC_MSM_OIS_CFG: + pr_err("%s: invalid cmd 0x%x received\n", __func__, cmd); + return -EINVAL; } rc = msm_ois_subdev_ioctl(sd, cmd, parg); diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c index 0871b1c8aea2588ab76f3e5a7b51565fe530e67e..8b307505f3733794cd4d71a8bc4ca24fab779f16 100644 --- a/drivers/scsi/sg.c +++ b/drivers/scsi/sg.c @@ -2082,11 +2082,12 @@ sg_get_rq_mark(Sg_fd * sfp, int pack_id) if ((1 == resp->done) && (!resp->sg_io_owned) && ((-1 == pack_id) || (resp->header.pack_id == pack_id))) { resp->done = 2; /* guard against other readers */ - break; + write_unlock_irqrestore(&sfp->rq_list_lock, iflags); + return resp; } } write_unlock_irqrestore(&sfp->rq_list_lock, iflags); - return resp; + return NULL; } /* always adds to end of list */ diff --git a/drivers/staging/qca-wifi-host-cmn/wmi/src/wmi_tlv_helper.c b/drivers/staging/qca-wifi-host-cmn/wmi/src/wmi_tlv_helper.c index 1246152010630ef6f81c9e3a19a81b26b4d46fd1..5c945cbb4bce661c2c5774823b6c8c73674a84ec 100644 --- a/drivers/staging/qca-wifi-host-cmn/wmi/src/wmi_tlv_helper.c +++ b/drivers/staging/qca-wifi-host-cmn/wmi/src/wmi_tlv_helper.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2016 The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2016, 2018 The Linux Foundation. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -505,6 +505,7 @@ wmitlv_check_and_pad_tlvs(void *os_handle, void *param_struc_ptr, wmitlv_cmd_param_info *cmd_param_tlvs_ptr = NULL; A_UINT32 remaining_expected_tlvs = 0xFFFFFFFF; A_UINT32 len_wmi_cmd_struct_buf; + A_UINT32 free_buf_len; A_INT32 error = -1; /* Get the number of TLVs for this command/event */ @@ -560,6 +561,13 @@ wmitlv_check_and_pad_tlvs(void *os_handle, void *param_struc_ptr, WMITLV_GET_TLVLEN(WMITLV_GET_HDR(buf_ptr)); int num_padding_bytes = 0; + free_buf_len = param_buf_len - (buf_idx + WMI_TLV_HDR_SIZE); + if (curr_tlv_len > free_buf_len) { + wmi_tlv_print_error("%s: TLV length overflow", + __func__); + goto Error_wmitlv_check_and_pad_tlvs; + } + /* Get the attributes of the TLV with the given order in "tlv_index" */ wmi_tlv_OS_MEMZERO(&attr_struct_ptr, sizeof(wmitlv_attributes_struc)); @@ -623,6 +631,13 @@ wmitlv_check_and_pad_tlvs(void *os_handle, void *param_struc_ptr, WMITLV_GET_TLVLEN(WMITLV_GET_HDR (buf_ptr)); in_tlv_len += WMI_TLV_HDR_SIZE; + if (in_tlv_len > curr_tlv_len) { + wmi_tlv_print_error("%s: Invalid in_tlv_len=%d", + __func__, + in_tlv_len); + goto + Error_wmitlv_check_and_pad_tlvs; + } tlv_size_diff = in_tlv_len - attr_struct_ptr.tag_struct_size; @@ -742,8 +757,17 @@ wmitlv_check_and_pad_tlvs(void *os_handle, void *param_struc_ptr, /* Move subsequent TLVs by number of bytes to be padded * for all elements */ - if (param_buf_len > - (buf_idx + curr_tlv_len)) { + if ((free_buf_len < + attr_struct_ptr.tag_struct_size * + num_of_elems) || + (param_buf_len < + buf_idx + curr_tlv_len + + num_padding_bytes * num_of_elems)) { + wmi_tlv_print_error("%s: Insufficent buffer\n", + __func__); + goto + Error_wmitlv_check_and_pad_tlvs; + } else { src_addr = buf_ptr + curr_tlv_len; dst_addr = @@ -763,12 +787,10 @@ wmitlv_check_and_pad_tlvs(void *os_handle, void *param_struc_ptr, * bytes to be padded for one element and alse set * padding bytes to zero */ tlv_buf_ptr = buf_ptr; - for (i = 0; i < num_of_elems; i++) { + for (i = 0; i < num_of_elems - 1; i++) { src_addr = tlv_buf_ptr + in_tlv_len; if (i != (num_of_elems - 1)) { - /* Need not move anything for last element - * in the array */ dst_addr = tlv_buf_ptr + in_tlv_len + @@ -791,6 +813,9 @@ wmitlv_check_and_pad_tlvs(void *os_handle, void *param_struc_ptr, attr_struct_ptr. tag_struct_size; } + src_addr = tlv_buf_ptr + in_tlv_len; + wmi_tlv_OS_MEMZERO(src_addr, + num_padding_bytes); /* Update the number of padding bytes to total number * of bytes padded for all elements in the array */ diff --git a/drivers/staging/qcacld-3.0/core/utils/fwlog/dbglog_host.c b/drivers/staging/qcacld-3.0/core/utils/fwlog/dbglog_host.c index ebf75e7a7d375e710566557079cee096dc008dd9..46e12c51ea42e30a3425e3443a53caa02c121ea8 100644 --- a/drivers/staging/qcacld-3.0/core/utils/fwlog/dbglog_host.c +++ b/drivers/staging/qcacld-3.0/core/utils/fwlog/dbglog_host.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2017 The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2018 The Linux Foundation. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -1480,7 +1480,7 @@ static int dbglog_print_raw_data(A_UINT32 *buffer, A_UINT32 length) char parseArgsString[DBGLOG_PARSE_ARGS_STRING_LENGTH]; char *dbgidString; - while (count < length) { + while ((count + 1) < length) { debugid = DBGLOG_GET_DBGID(buffer[count + 1]); moduleid = DBGLOG_GET_MODULEID(buffer[count + 1]); @@ -1493,6 +1493,9 @@ static int dbglog_print_raw_data(A_UINT32 *buffer, A_UINT32 length) OS_MEMZERO(parseArgsString, sizeof(parseArgsString)); totalWriteLen = 0; + if (!numargs || (count + numargs + 2 > length)) + goto skip_args_processing; + for (curArgs = 0; curArgs < numargs; curArgs++) { /* * Using sprintf_s instead of sprintf, @@ -1505,7 +1508,7 @@ static int dbglog_print_raw_data(A_UINT32 *buffer, A_UINT32 length) buffer[count + 2 + curArgs]); totalWriteLen += writeLen; } - +skip_args_processing: if (debugid < MAX_DBG_MSGS) { dbgidString = DBG_MSG_ARR[moduleid][debugid]; if (dbgidString != NULL) { @@ -1977,6 +1980,11 @@ int dbglog_parse_debug_logs(ol_scn_t scn, uint8_t *data, uint32_t datalen) len = param_buf->num_bufp; } + if (len < sizeof(dropped)) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Invalid length\n")); + return A_ERROR; + } + dropped = *((A_UINT32 *) datap); if (dropped > 0) { AR_DEBUG_PRINTF(ATH_DEBUG_TRC, diff --git a/drivers/usb/gadget/function/f_hid.c b/drivers/usb/gadget/function/f_hid.c index ee579ba2b59e65f1bda2cf14a878f870068139f5..a5dae5bb62abc194a5b7f8f73f0fc9d14c9d8ee8 100644 --- a/drivers/usb/gadget/function/f_hid.c +++ b/drivers/usb/gadget/function/f_hid.c @@ -223,6 +223,13 @@ static ssize_t f_hidg_read(struct file *file, char __user *buffer, /* pick the first one */ list = list_first_entry(&hidg->completed_out_req, struct f_hidg_req_list, list); + + /* + * Remove this from list to protect it from beign free() + * while host disables our function + */ + list_del(&list->list); + req = list->req; count = min_t(unsigned int, count, req->actual - list->pos); spin_unlock_irqrestore(&hidg->spinlock, flags); @@ -238,15 +245,20 @@ static ssize_t f_hidg_read(struct file *file, char __user *buffer, * call, taking into account its current read position. */ if (list->pos == req->actual) { - spin_lock_irqsave(&hidg->spinlock, flags); - list_del(&list->list); kfree(list); - spin_unlock_irqrestore(&hidg->spinlock, flags); req->length = hidg->report_length; ret = usb_ep_queue(hidg->out_ep, req, GFP_KERNEL); - if (ret < 0) + if (ret < 0) { + free_ep_req(hidg->out_ep, req); return ret; + } + } else { + spin_lock_irqsave(&hidg->spinlock, flags); + list_add(&list->list, &hidg->completed_out_req); + spin_unlock_irqrestore(&hidg->spinlock, flags); + + wake_up(&hidg->read_queue); } return count; @@ -490,14 +502,18 @@ static void hidg_disable(struct usb_function *f) { struct f_hidg *hidg = func_to_hidg(f); struct f_hidg_req_list *list, *next; + unsigned long flags; usb_ep_disable(hidg->in_ep); usb_ep_disable(hidg->out_ep); + spin_lock_irqsave(&hidg->spinlock, flags); list_for_each_entry_safe(list, next, &hidg->completed_out_req, list) { + free_ep_req(hidg->out_ep, list->req); list_del(&list->list); kfree(list); } + spin_unlock_irqrestore(&hidg->spinlock, flags); } static int hidg_set_alt(struct usb_function *f, unsigned intf, unsigned alt) diff --git a/drivers/usb/gadget/function/f_midi.c b/drivers/usb/gadget/function/f_midi.c index c9b2ed8c7eabda7f637eef26658e6a93fc5f4ba8..c824466104eacc3e24a0a78cb70dbb8892ce36f1 100644 --- a/drivers/usb/gadget/function/f_midi.c +++ b/drivers/usb/gadget/function/f_midi.c @@ -219,12 +219,6 @@ static inline struct usb_request *midi_alloc_ep_req(struct usb_ep *ep, return alloc_ep_req(ep, length, length); } -static void free_ep_req(struct usb_ep *ep, struct usb_request *req) -{ - kfree(req->buf); - usb_ep_free_request(ep, req); -} - static const uint8_t f_midi_cin_length[] = { 0, 0, 2, 3, 3, 1, 2, 3, 3, 3, 3, 3, 2, 2, 3, 1 }; diff --git a/drivers/usb/gadget/function/f_sourcesink.c b/drivers/usb/gadget/function/f_sourcesink.c index 9f3ced62d9162c991c03b0db68d10fd0cbe06ea9..67b24398993898dd556f8e6a921f0ad093d2bc09 100644 --- a/drivers/usb/gadget/function/f_sourcesink.c +++ b/drivers/usb/gadget/function/f_sourcesink.c @@ -303,12 +303,6 @@ static inline struct usb_request *ss_alloc_ep_req(struct usb_ep *ep, int len) return alloc_ep_req(ep, len, ss->buflen); } -void free_ep_req(struct usb_ep *ep, struct usb_request *req) -{ - kfree(req->buf); - usb_ep_free_request(ep, req); -} - static void disable_ep(struct usb_composite_dev *cdev, struct usb_ep *ep) { int value; diff --git a/drivers/usb/gadget/function/g_zero.h b/drivers/usb/gadget/function/g_zero.h index 15f180904f8a3980e2845c38bf327e5174b8df30..5ed90b437f18005a654dd703ae31d4cc9f1cf4dd 100644 --- a/drivers/usb/gadget/function/g_zero.h +++ b/drivers/usb/gadget/function/g_zero.h @@ -59,7 +59,6 @@ void lb_modexit(void); int lb_modinit(void); /* common utilities */ -void free_ep_req(struct usb_ep *ep, struct usb_request *req); void disable_endpoints(struct usb_composite_dev *cdev, struct usb_ep *in, struct usb_ep *out, struct usb_ep *iso_in, struct usb_ep *iso_out); diff --git a/drivers/usb/gadget/u_f.c b/drivers/usb/gadget/u_f.c index c6276f0268ae51e0b9669db69ebbb58c46e794ba..4bc7eea8bfc84d0c941b8ba7ec743e1db313db97 100644 --- a/drivers/usb/gadget/u_f.c +++ b/drivers/usb/gadget/u_f.c @@ -11,7 +11,6 @@ * published by the Free Software Foundation. */ -#include <linux/usb/gadget.h> #include "u_f.h" struct usb_request *alloc_ep_req(struct usb_ep *ep, int len, int default_len) diff --git a/drivers/usb/gadget/u_f.h b/drivers/usb/gadget/u_f.h index 1d5f0eb685521c3a3ce6942571b78413161c54ef..4247cc098a8915c49286ff4c57978f77d89f1125 100644 --- a/drivers/usb/gadget/u_f.h +++ b/drivers/usb/gadget/u_f.h @@ -16,6 +16,8 @@ #ifndef __U_F_H__ #define __U_F_H__ +#include <linux/usb/gadget.h> + /* Variable Length Array Macros **********************************************/ #define vla_group(groupname) size_t groupname##__next = 0 #define vla_group_size(groupname) groupname##__next @@ -45,8 +47,12 @@ struct usb_ep; struct usb_request; +/* Requests allocated via alloc_ep_req() must be freed by free_ep_req(). */ struct usb_request *alloc_ep_req(struct usb_ep *ep, int len, int default_len); +static inline void free_ep_req(struct usb_ep *ep, struct usb_request *req) +{ + kfree(req->buf); + usb_ep_free_request(ep, req); +} #endif /* __U_F_H__ */ - - diff --git a/kernel/futex.c b/kernel/futex.c index ef66da18fe8f672addfd41d2e4542a88b40dccc6..14474bfb16996510ba34bd4941d022f490ddd489 100644 --- a/kernel/futex.c +++ b/kernel/futex.c @@ -470,6 +470,7 @@ get_futex_key(u32 __user *uaddr, int fshared, union futex_key *key, int rw) unsigned long address = (unsigned long)uaddr; struct mm_struct *mm = current->mm; struct page *page, *page_head; + struct address_space *mapping; int err, ro = 0; /* @@ -555,7 +556,19 @@ again: } #endif - lock_page(page_head); + /* + * The treatment of mapping from this point on is critical. The page + * lock protects many things but in this context the page lock + * stabilizes mapping, prevents inode freeing in the shared + * file-backed region case and guards against movement to swap cache. + * + * Strictly speaking the page lock is not needed in all cases being + * considered here and page lock forces unnecessarily serialization + * From this point on, mapping will be re-verified if necessary and + * page lock will be acquired only if it is unavoidable + */ + + mapping = READ_ONCE(page_head->mapping); /* * If page_head->mapping is NULL, then it cannot be a PageAnon @@ -572,18 +585,31 @@ again: * shmem_writepage move it from filecache to swapcache beneath us: * an unlikely race, but we do need to retry for page_head->mapping. */ - if (!page_head->mapping) { - int shmem_swizzled = PageSwapCache(page_head); + if (unlikely(!mapping)) { + int shmem_swizzled; + + /* + * Page lock is required to identify which special case above + * applies. If this is really a shmem page then the page lock + * will prevent unexpected transitions. + */ + lock_page(page); + shmem_swizzled = PageSwapCache(page) || page->mapping; unlock_page(page_head); put_page(page_head); + if (shmem_swizzled) goto again; + return -EFAULT; } /* * Private mappings are handled in a simple way. * + * If the futex key is stored on an anonymous page, then the associated + * object is the mm which is implicitly pinned by the calling process. + * * NOTE: When userspace waits on a MAP_SHARED mapping, even if * it's a read-only handle, it's expected that futexes attach to * the object not the particular process. @@ -601,16 +627,74 @@ again: key->both.offset |= FUT_OFF_MMSHARED; /* ref taken on mm */ key->private.mm = mm; key->private.address = address; + + get_futex_key_refs(key); /* implies smp_mb(); (B) */ + } else { + struct inode *inode; + + /* + * The associated futex object in this case is the inode and + * the page->mapping must be traversed. Ordinarily this should + * be stabilised under page lock but it's not strictly + * necessary in this case as we just want to pin the inode, not + * update the radix tree or anything like that. + * + * The RCU read lock is taken as the inode is finally freed + * under RCU. If the mapping still matches expectations then the + * mapping->host can be safely accessed as being a valid inode. + */ + rcu_read_lock(); + + if (READ_ONCE(page_head->mapping) != mapping) { + rcu_read_unlock(); + put_page(page_head); + + goto again; + } + + inode = READ_ONCE(mapping->host); + if (!inode) { + rcu_read_unlock(); + put_page(page_head); + + goto again; + } + + /* + * Take a reference unless it is about to be freed. Previously + * this reference was taken by ihold under the page lock + * pinning the inode in place so i_lock was unnecessary. The + * only way for this check to fail is if the inode was + * truncated in parallel so warn for now if this happens. + * + * We are not calling into get_futex_key_refs() in file-backed + * cases, therefore a successful atomic_inc return below will + * guarantee that get_futex_key() will still imply smp_mb(); (B). + */ + if (WARN_ON_ONCE(!atomic_inc_not_zero(&inode->i_count))) { + rcu_read_unlock(); + put_page(page_head); + + goto again; + } + + /* Should be impossible but lets be paranoid for now */ + if (WARN_ON_ONCE(inode->i_mapping != mapping)) { + err = -EFAULT; + rcu_read_unlock(); + iput(inode); + + goto out; + } + key->both.offset |= FUT_OFF_INODE; /* inode-based key */ - key->shared.inode = page_head->mapping->host; + key->shared.inode = inode; key->shared.pgoff = basepage_index(page); + rcu_read_unlock(); } - get_futex_key_refs(key); /* implies MB (B) */ - out: - unlock_page(page_head); put_page(page_head); return err; } @@ -1621,6 +1705,9 @@ static int futex_requeue(u32 __user *uaddr1, unsigned int flags, struct futex_q *this, *next; WAKE_Q(wake_q); + if (nr_wake < 0 || nr_requeue < 0) + return -EINVAL; + if (requeue_pi) { /* * Requeue PI only works on two distinct uaddrs. This diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c index 6e3e0e8b1ce3254a96220a82f40dc2a36703cc6f..cff58f7ee55919978396d91400da3be9a2f42fa1 100644 --- a/net/ipv4/netfilter/arp_tables.c +++ b/net/ipv4/netfilter/arp_tables.c @@ -329,6 +329,10 @@ unsigned int arpt_do_table(struct sk_buff *skb, } if (table_base + v != arpt_next_entry(e)) { + if (unlikely(stackidx >= private->stacksize)) { + verdict = NF_DROP; + break; + } jumpstack[stackidx++] = e; } diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c index a399c5419622d5f47acd74922bb3771fc55bad73..760c81dfbee8c9cb26fedd15d6f11c498c491ef3 100644 --- a/net/ipv4/netfilter/ip_tables.c +++ b/net/ipv4/netfilter/ip_tables.c @@ -408,6 +408,10 @@ ipt_do_table(struct sk_buff *skb, } if (table_base + v != ipt_next_entry(e) && !(e->ip.flags & IPT_F_GOTO)) { + if (unlikely(stackidx >= private->stacksize)) { + verdict = NF_DROP; + break; + } jumpstack[stackidx++] = e; pr_debug("Pushed %p into pos %u\n", e, stackidx - 1); diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c index 6fd784643d6efa12609dd7272d83ee3abc696e23..3d616c6733e5f06b3c9a83ee34d7dc7c23679f77 100644 --- a/net/ipv6/netfilter/ip6_tables.c +++ b/net/ipv6/netfilter/ip6_tables.c @@ -429,6 +429,10 @@ ip6t_do_table(struct sk_buff *skb, } if (table_base + v != ip6t_next_entry(e) && !(e->ipv6.flags & IP6T_F_GOTO)) { + if (unlikely(stackidx >= private->stacksize)) { + verdict = NF_DROP; + break; + } jumpstack[stackidx++] = e; } diff --git a/sound/soc/msm/qdsp6v2/msm-qti-pp-config.c b/sound/soc/msm/qdsp6v2/msm-qti-pp-config.c index d4e78604f868b80c64f964d2883cabed4b2d583d..5258d392fd50a6bd64f1962cc1118528545e1348 100644 --- a/sound/soc/msm/qdsp6v2/msm-qti-pp-config.c +++ b/sound/soc/msm/qdsp6v2/msm-qti-pp-config.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 @@ -25,6 +25,7 @@ #include "msm-qti-pp-config.h" #include "msm-pcm-routing-v2.h" +#define MAX_MIXER_CTL_BUF_SIZE 512 /* EQUALIZER */ /* Equal to Frontend after last of the MULTIMEDIA SESSIONS */ #define MAX_EQ_SESSIONS MSM_FRONTEND_DAI_CS_VOICE @@ -877,7 +878,7 @@ int msm_adsp_stream_cmd_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES; - uinfo->count = 512; + uinfo->count = MAX_MIXER_CTL_BUF_SIZE; return 0; } @@ -890,6 +891,12 @@ int msm_adsp_stream_callback_put(struct snd_kcontrol *kcontrol, /* fetch payload size in first four bytes */ memcpy(&payload_size, ucontrol->value.bytes.data, sizeof(uint32_t)); + if (payload_size > MAX_MIXER_CTL_BUF_SIZE - sizeof(payload_size)) { + pr_err("%s: payload_size=%d is over mixer ctl buffer limit.", + __func__, payload_size); + return -EINVAL; + } + if (kcontrol->private_data == NULL) { /* buffer is empty */ kcontrol->private_data = @@ -942,7 +949,7 @@ int msm_adsp_stream_callback_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES; - uinfo->count = 512; + uinfo->count = MAX_MIXER_CTL_BUF_SIZE; return 0; } diff --git a/sound/soc/msm/qdsp6v2/q6asm.c b/sound/soc/msm/qdsp6v2/q6asm.c index 6426e0b365eb1d773bb197d9a32e70f261ad8a63..b1a061fe85809d4692237a7e9213e6005bec0cd3 100644 --- a/sound/soc/msm/qdsp6v2/q6asm.c +++ b/sound/soc/msm/qdsp6v2/q6asm.c @@ -247,6 +247,11 @@ static ssize_t audio_output_latency_dbgfs_read(struct file *file, pr_err("%s: out_buffer is null\n", __func__); return 0; } + if (count < OUT_BUFFER_SIZE) { + pr_err("%s: read size %d exceeds buf size %zd\n", __func__, + OUT_BUFFER_SIZE, count); + return 0; + } snprintf(out_buffer, OUT_BUFFER_SIZE, "%ld,%ld,%ld,%ld,%ld,%ld,",\ out_cold_tv.tv_sec, out_cold_tv.tv_usec, out_warm_tv.tv_sec,\ out_warm_tv.tv_usec, out_cont_tv.tv_sec, out_cont_tv.tv_usec); @@ -300,6 +305,11 @@ static ssize_t audio_input_latency_dbgfs_read(struct file *file, pr_err("%s: in_buffer is null\n", __func__); return 0; } + if (count < IN_BUFFER_SIZE) { + pr_err("%s: read size %d exceeds buf size %zd\n", __func__, + IN_BUFFER_SIZE, count); + return 0; + } snprintf(in_buffer, IN_BUFFER_SIZE, "%ld,%ld,",\ in_cont_tv.tv_sec, in_cont_tv.tv_usec); return simple_read_from_buffer(buf, IN_BUFFER_SIZE, ppos,