From d7fe6c3e4667db809f0f647dc5be1a0382629524 Mon Sep 17 00:00:00 2001 From: Tammy Leino Date: Fri, 23 Sep 2022 13:00:14 -0700 Subject: [PATCH] Additional input parameter checks for APIs Added additional input parameter checks to APIs Signed-off-by: Tammy Leino --- lib/include/openamp/remoteproc.h | 2 +- lib/include/openamp/rpmsg.h | 18 +++++ lib/include/openamp/rpmsg_virtio.h | 3 + lib/remoteproc/remoteproc.c | 111 +++++++++++++++++++---------- lib/remoteproc/remoteproc_virtio.c | 3 +- lib/remoteproc/rsc_table_parser.c | 3 + lib/rpmsg/rpmsg.c | 10 ++- lib/rpmsg/rpmsg_virtio.c | 27 ++++--- 8 files changed, 121 insertions(+), 56 deletions(-) diff --git a/lib/include/openamp/remoteproc.h b/lib/include/openamp/remoteproc.h index 41f5d5741..fed87ec38 100644 --- a/lib/include/openamp/remoteproc.h +++ b/lib/include/openamp/remoteproc.h @@ -535,7 +535,7 @@ remoteproc_init_mem(struct remoteproc_mem *mem, const char *name, metal_phys_addr_t pa, metal_phys_addr_t da, size_t size, struct metal_io_region *io) { - if (!mem) + if (!mem || !io || size == 0) return; if (name) strncpy(mem->name, name, sizeof(mem->name)); diff --git a/lib/include/openamp/rpmsg.h b/lib/include/openamp/rpmsg.h index 5b2d5bed8..09a472678 100644 --- a/lib/include/openamp/rpmsg.h +++ b/lib/include/openamp/rpmsg.h @@ -161,6 +161,9 @@ int rpmsg_send_offchannel_raw(struct rpmsg_endpoint *ept, uint32_t src, static inline int rpmsg_send(struct rpmsg_endpoint *ept, const void *data, int len) { + if (!ept) + return RPMSG_ERR_PARAM; + return rpmsg_send_offchannel_raw(ept, ept->addr, ept->dest_addr, data, len, true); } @@ -184,6 +187,9 @@ static inline int rpmsg_send(struct rpmsg_endpoint *ept, const void *data, static inline int rpmsg_sendto(struct rpmsg_endpoint *ept, const void *data, int len, uint32_t dst) { + if (!ept) + return RPMSG_ERR_PARAM; + return rpmsg_send_offchannel_raw(ept, ept->addr, dst, data, len, true); } @@ -229,6 +235,9 @@ static inline int rpmsg_send_offchannel(struct rpmsg_endpoint *ept, static inline int rpmsg_trysend(struct rpmsg_endpoint *ept, const void *data, int len) { + if (!ept) + return RPMSG_ERR_PARAM; + return rpmsg_send_offchannel_raw(ept, ept->addr, ept->dest_addr, data, len, false); } @@ -252,6 +261,9 @@ static inline int rpmsg_trysend(struct rpmsg_endpoint *ept, const void *data, static inline int rpmsg_trysendto(struct rpmsg_endpoint *ept, const void *data, int len, uint32_t dst) { + if (!ept) + return RPMSG_ERR_PARAM; + return rpmsg_send_offchannel_raw(ept, ept->addr, dst, data, len, false); } @@ -401,6 +413,9 @@ int rpmsg_send_offchannel_nocopy(struct rpmsg_endpoint *ept, uint32_t src, static inline int rpmsg_sendto_nocopy(struct rpmsg_endpoint *ept, const void *data, int len, uint32_t dst) { + if (!ept) + return RPMSG_ERR_PARAM; + return rpmsg_send_offchannel_nocopy(ept, ept->addr, dst, data, len); } @@ -435,6 +450,9 @@ static inline int rpmsg_sendto_nocopy(struct rpmsg_endpoint *ept, static inline int rpmsg_send_nocopy(struct rpmsg_endpoint *ept, const void *data, int len) { + if (!ept) + return RPMSG_ERR_PARAM; + return rpmsg_send_offchannel_nocopy(ept, ept->addr, ept->dest_addr, data, len); } diff --git a/lib/include/openamp/rpmsg_virtio.h b/lib/include/openamp/rpmsg_virtio.h index ff1e17119..a64d4f433 100644 --- a/lib/include/openamp/rpmsg_virtio.h +++ b/lib/include/openamp/rpmsg_virtio.h @@ -240,6 +240,9 @@ void rpmsg_virtio_init_shm_pool(struct rpmsg_virtio_shm_pool *shpool, static inline struct rpmsg_device * rpmsg_virtio_get_rpmsg_device(struct rpmsg_virtio_device *rvdev) { + if (!rvdev) + return NULL; + return &rvdev->rdev; } diff --git a/lib/remoteproc/remoteproc.c b/lib/remoteproc/remoteproc.c index 9a0cf3e01..2f700dd9c 100644 --- a/lib/remoteproc/remoteproc.c +++ b/lib/remoteproc/remoteproc.c @@ -142,6 +142,9 @@ static int remoteproc_parse_rsc_table(struct remoteproc *rproc, { struct metal_io_region *io; + if (!rsc_table) + return -RPROC_EINVAL; + io = remoteproc_get_io_with_va(rproc, rsc_table); return handle_rsc_table(rproc, rsc_table, rsc_size, io); } @@ -153,6 +156,9 @@ int remoteproc_set_rsc_table(struct remoteproc *rproc, int ret; struct metal_io_region *io; + if (!rproc || !rsc_table || rsc_size == 0) + return -RPROC_EINVAL; + io = remoteproc_get_io_with_va(rproc, rsc_table); if (!io) return -RPROC_EINVAL; @@ -168,13 +174,14 @@ int remoteproc_set_rsc_table(struct remoteproc *rproc, struct remoteproc *remoteproc_init(struct remoteproc *rproc, const struct remoteproc_ops *ops, void *priv) { - if (rproc) { - memset(rproc, 0, sizeof(*rproc)); - rproc->state = RPROC_OFFLINE; - metal_mutex_init(&rproc->lock); - metal_list_init(&rproc->mems); - metal_list_init(&rproc->vdevs); - } + if (!rproc || !ops) + return NULL; + + memset(rproc, 0, sizeof(*rproc)); + rproc->state = RPROC_OFFLINE; + metal_mutex_init(&rproc->lock); + metal_list_init(&rproc->mems); + metal_list_init(&rproc->vdevs); rproc = ops->init(rproc, ops, priv); return rproc; } @@ -183,16 +190,17 @@ int remoteproc_remove(struct remoteproc *rproc) { int ret = 0; - if (rproc) { - metal_mutex_acquire(&rproc->lock); - if (rproc->state == RPROC_OFFLINE) + if (!rproc) + return -RPROC_EINVAL; + + metal_mutex_acquire(&rproc->lock); + if (rproc->state == RPROC_OFFLINE) { + if (rproc->ops->remove) rproc->ops->remove(rproc); - else - ret = -RPROC_EAGAIN; - metal_mutex_release(&rproc->lock); } else { - ret = -RPROC_EINVAL; + ret = -RPROC_EAGAIN; } + metal_mutex_release(&rproc->lock); return ret; } @@ -288,12 +296,15 @@ remoteproc_get_io_with_name(struct remoteproc *rproc, struct remoteproc_mem *mem; struct remoteproc_mem buf; + if (!rproc) + return NULL; + mem = remoteproc_get_mem(rproc, name, METAL_BAD_PHYS, METAL_BAD_PHYS, NULL, 0, &buf); if (mem) return mem->io; - else - return NULL; + + return NULL; } struct metal_io_region * @@ -303,11 +314,14 @@ remoteproc_get_io_with_pa(struct remoteproc *rproc, struct remoteproc_mem *mem; struct remoteproc_mem buf; + if (!rproc) + return NULL; + mem = remoteproc_get_mem(rproc, NULL, pa, METAL_BAD_PHYS, NULL, 0, &buf); if (mem) return mem->io; - else - return NULL; + + return NULL; } struct metal_io_region * @@ -318,6 +332,9 @@ remoteproc_get_io_with_da(struct remoteproc *rproc, struct remoteproc_mem *mem; struct remoteproc_mem buf; + if (!rproc || !offset) + return NULL; + mem = remoteproc_get_mem(rproc, NULL, METAL_BAD_PHYS, da, NULL, 0, &buf); if (mem) { struct metal_io_region *io; @@ -327,9 +344,9 @@ remoteproc_get_io_with_da(struct remoteproc *rproc, pa = remoteproc_datopa(mem, da); *offset = metal_io_phys_to_offset(io, pa); return io; - } else { - return NULL; } + + return NULL; } struct metal_io_region * @@ -338,12 +355,15 @@ remoteproc_get_io_with_va(struct remoteproc *rproc, void *va) struct remoteproc_mem *mem; struct remoteproc_mem buf; + if (!rproc) + return NULL; + mem = remoteproc_get_mem(rproc, NULL, METAL_BAD_PHYS, METAL_BAD_PHYS, va, 0, &buf); if (mem) return mem->io; - else - return NULL; + + return NULL; } void *remoteproc_mmap(struct remoteproc *rproc, @@ -356,9 +376,7 @@ void *remoteproc_mmap(struct remoteproc *rproc, struct remoteproc_mem *mem; struct remoteproc_mem buf; - if (!rproc) - return NULL; - else if (!pa && !da) + if (!rproc || size == 0 || (!pa && !da)) return NULL; if (pa) lpa = *pa; @@ -853,20 +871,21 @@ unsigned int remoteproc_allocate_id(struct remoteproc *rproc, unsigned int start, unsigned int end) { - unsigned int notifyid; + unsigned int notifyid = RSC_NOTIFY_ID_ANY; if (start == RSC_NOTIFY_ID_ANY) start = 0; if (end == 0) end = METAL_BITS_PER_ULONG; - - notifyid = metal_bitmap_next_clear_bit(&rproc->bitmap, - start, end); - if (notifyid != end) - metal_bitmap_set_bit(&rproc->bitmap, notifyid); - else - notifyid = RSC_NOTIFY_ID_ANY; - + if ((start < (8U * sizeof(rproc->bitmap))) && + (end <= (8U * sizeof(rproc->bitmap)))) { + notifyid = metal_bitmap_next_clear_bit(&rproc->bitmap, + start, end); + if (notifyid != end) + metal_bitmap_set_bit(&rproc->bitmap, notifyid); + else + notifyid = RSC_NOTIFY_ID_ANY; + } return notifyid; } @@ -895,6 +914,17 @@ remoteproc_create_virtio(struct remoteproc *rproc, unsigned int num_vrings, i; struct metal_list *node; +#ifdef VIRTIO_DRIVER_ONLY + role = (role != VIRTIO_DEV_DRIVER) ? 0xFFFFFFFFUL : role; +#endif + +#ifdef VIRTIO_DEVICE_ONLY + role = (role != VIRTIO_DEV_DEVICE) ? 0xFFFFFFFFUL : role; +#endif + + if (!rproc || (role != VIRTIO_DEV_DEVICE && role != VIRTIO_DEV_DRIVER)) + return NULL; + metal_assert(rproc); metal_mutex_acquire(&rproc->lock); rsc_table = rproc->rsc_table; @@ -970,9 +1000,12 @@ void remoteproc_remove_virtio(struct remoteproc *rproc, (void)rproc; metal_assert(vdev); - rpvdev = metal_container_of(vdev, struct remoteproc_virtio, vdev); - metal_list_del(&rpvdev->node); - rproc_virtio_remove_vdev(&rpvdev->vdev); + + if (vdev) { + rpvdev = metal_container_of(vdev, struct remoteproc_virtio, vdev); + metal_list_del(&rpvdev->node); + rproc_virtio_remove_vdev(&rpvdev->vdev); + } } int remoteproc_get_notification(struct remoteproc *rproc, uint32_t notifyid) @@ -981,6 +1014,9 @@ int remoteproc_get_notification(struct remoteproc *rproc, uint32_t notifyid) struct metal_list *node; int ret; + if (!rproc) + return 0; + metal_list_for_each(&rproc->vdevs, node) { rpvdev = metal_container_of(node, struct remoteproc_virtio, node); @@ -988,5 +1024,6 @@ int remoteproc_get_notification(struct remoteproc *rproc, uint32_t notifyid) if (ret) return ret; } + return 0; } diff --git a/lib/remoteproc/remoteproc_virtio.c b/lib/remoteproc/remoteproc_virtio.c index a623276ea..6677b2355 100644 --- a/lib/remoteproc/remoteproc_virtio.c +++ b/lib/remoteproc/remoteproc_virtio.c @@ -283,7 +283,8 @@ void rproc_virtio_remove_vdev(struct virtio_device *vdev) if (vq) metal_free_memory(vq); } - metal_free_memory(vdev->vrings_info); + if (vdev->vrings_info) + metal_free_memory(vdev->vrings_info); metal_free_memory(rpvdev); } diff --git a/lib/remoteproc/rsc_table_parser.c b/lib/remoteproc/rsc_table_parser.c index 6ee7db6e9..56ef59a7d 100644 --- a/lib/remoteproc/rsc_table_parser.c +++ b/lib/remoteproc/rsc_table_parser.c @@ -201,6 +201,9 @@ size_t find_rsc(void *rsc_table, unsigned int rsc_type, unsigned int index) unsigned int lrsc_type; metal_assert(r_table); + if (!r_table) + return 0; + /* Loop through the offset array and parse each resource entry */ rsc_index = 0; for (i = 0; i < r_table->num; i++) { diff --git a/lib/rpmsg/rpmsg.c b/lib/rpmsg/rpmsg.c index 214b2a98e..9322c3dba 100644 --- a/lib/rpmsg/rpmsg.c +++ b/lib/rpmsg/rpmsg.c @@ -115,7 +115,7 @@ int rpmsg_send_offchannel_raw(struct rpmsg_endpoint *ept, uint32_t src, { struct rpmsg_device *rdev; - if (!ept || !ept->rdev || !data || dst == RPMSG_ADDR_ANY) + if (!ept || !ept->rdev || !data || dst == RPMSG_ADDR_ANY || len < 0) return RPMSG_ERR_PARAM; rdev = ept->rdev; @@ -191,7 +191,7 @@ int rpmsg_send_offchannel_nocopy(struct rpmsg_endpoint *ept, uint32_t src, { struct rpmsg_device *rdev; - if (!ept || !ept->rdev || !data || dst == RPMSG_ADDR_ANY) + if (!ept || !ept->rdev || !data || dst == RPMSG_ADDR_ANY || len < 0) return RPMSG_ERR_PARAM; rdev = ept->rdev; @@ -269,7 +269,7 @@ int rpmsg_create_ept(struct rpmsg_endpoint *ept, struct rpmsg_device *rdev, int status = RPMSG_SUCCESS; uint32_t addr = src; - if (!ept) + if (!ept || !rdev || !cb) return RPMSG_ERR_PARAM; metal_mutex_acquire(&rdev->lock); @@ -328,12 +328,10 @@ void rpmsg_destroy_ept(struct rpmsg_endpoint *ept) { struct rpmsg_device *rdev; - if (!ept) + if (!ept || !ept->rdev) return; rdev = ept->rdev; - if (!rdev) - return; if (ept->name[0] && rdev->support_ns && ept->addr >= RPMSG_RESERVED_ADDRESSES) diff --git a/lib/rpmsg/rpmsg_virtio.c b/lib/rpmsg/rpmsg_virtio.c index cd08f40b7..811a7a643 100644 --- a/lib/rpmsg/rpmsg_virtio.c +++ b/lib/rpmsg/rpmsg_virtio.c @@ -44,7 +44,7 @@ rpmsg_virtio_shm_pool_get_buffer(struct rpmsg_virtio_shm_pool *shpool, { void *buffer; - if (shpool->avail < size) + if (!shpool || size == 0 || shpool->avail < size) return NULL; buffer = (char *)shpool->base + shpool->size - shpool->avail; shpool->avail -= size; @@ -56,7 +56,7 @@ rpmsg_virtio_shm_pool_get_buffer(struct rpmsg_virtio_shm_pool *shpool, void rpmsg_virtio_init_shm_pool(struct rpmsg_virtio_shm_pool *shpool, void *shb, size_t size) { - if (!shpool) + if (!shpool || !shb || size == 0) return; shpool->base = shb; shpool->size = size; @@ -644,6 +644,9 @@ int rpmsg_init_vdev_with_config(struct rpmsg_virtio_device *rvdev, int status; unsigned int i, role; + if (!rvdev || !vdev || !shm_io) + return RPMSG_ERR_PARAM; + rdev = &rvdev->rdev; memset(rdev, 0, sizeof(*rdev)); metal_mutex_init(&rdev->lock); @@ -797,15 +800,17 @@ void rpmsg_deinit_vdev(struct rpmsg_virtio_device *rvdev) struct rpmsg_device *rdev; struct rpmsg_endpoint *ept; - rdev = &rvdev->rdev; - while (!metal_list_is_empty(&rdev->endpoints)) { - node = rdev->endpoints.next; - ept = metal_container_of(node, struct rpmsg_endpoint, node); - rpmsg_destroy_ept(ept); - } + if (rvdev) { + rdev = &rvdev->rdev; + while (!metal_list_is_empty(&rdev->endpoints)) { + node = rdev->endpoints.next; + ept = metal_container_of(node, struct rpmsg_endpoint, node); + rpmsg_destroy_ept(ept); + } - rvdev->rvq = 0; - rvdev->svq = 0; + rvdev->rvq = 0; + rvdev->svq = 0; - metal_mutex_deinit(&rdev->lock); + metal_mutex_deinit(&rdev->lock); + } }