diff --git a/drivers/soc/qcom/mem-buf.c b/drivers/soc/qcom/mem-buf.c index ad34a20e2ccc..969fb10585fe 100644 --- a/drivers/soc/qcom/mem-buf.c +++ b/drivers/soc/qcom/mem-buf.c @@ -1128,6 +1128,9 @@ static int mem_buf_vmid_to_vmid(u32 mem_buf_vmid) hh_vmid_t vmid; enum hh_vm_names vm_name; + if (!is_valid_mem_buf_vmid(mem_buf_vmid)) + return -EINVAL; + if (mem_buf_vmid == MEM_BUF_VMID_PRIMARY_VM) vm_name = HH_PRIMARY_VM; else if (mem_buf_vmid == MEM_BUF_VMID_TRUSTED_VM) @@ -1145,6 +1148,9 @@ static int mem_buf_perms_to_perms(u32 mem_buf_perms) { int perms = 0; + if (!is_valid_mem_buf_perms(mem_buf_perms)) + return -EINVAL; + if (mem_buf_perms & MEM_BUF_PERM_FLAG_READ) perms |= PERM_READ; if (mem_buf_perms & MEM_BUF_PERM_FLAG_WRITE) @@ -1173,13 +1179,12 @@ static struct hh_acl_desc *mem_buf_acl_to_hh_acl(unsigned int nr_acl_entries, for (i = 0; i < nr_acl_entries; i++) { mem_buf_vmid = entries[i].vmid; mem_buf_perms = entries[i].perms; - if (!is_valid_mem_buf_vmid(mem_buf_vmid) || - !is_valid_mem_buf_perms(mem_buf_perms)) { + vmid = mem_buf_vmid_to_vmid(mem_buf_vmid); + perms = mem_buf_perms_to_perms(mem_buf_perms); + if (vmid < 0 || perms < 0) { ret = -EINVAL; goto err_inv_vmid_perms; } - vmid = mem_buf_vmid_to_vmid(mem_buf_vmid); - perms = mem_buf_perms_to_perms(mem_buf_perms); acl_desc->acl_entries[i].vmid = vmid; acl_desc->acl_entries[i].perms = perms; } @@ -1266,6 +1271,12 @@ static const struct file_operations mem_buf_fops = { .release = mem_buf_buffer_release, }; +static bool is_valid_mem_type(enum mem_buf_mem_type mem_type) +{ + return mem_type >= MEM_BUF_ION_MEM_TYPE && + mem_type < MEM_BUF_MAX_MEM_TYPE; +} + void *mem_buf_alloc(struct mem_buf_allocation_data *alloc_data) { int ret; @@ -1275,7 +1286,11 @@ void *mem_buf_alloc(struct mem_buf_allocation_data *alloc_data) if (!(mem_buf_capability & MEM_BUF_CAP_CONSUMER)) return ERR_PTR(-ENOTSUPP); - if (!alloc_data) + if (!alloc_data || !alloc_data->size || !alloc_data->nr_acl_entries || + !alloc_data->acl_list || + (alloc_data->nr_acl_entries > MEM_BUF_MAX_NR_ACL_ENTS) || + !is_valid_mem_type(alloc_data->src_mem_type) || + !is_valid_mem_type(alloc_data->dst_mem_type)) return ERR_PTR(-EINVAL); membuf = kzalloc(sizeof(*membuf), GFP_KERNEL); @@ -1363,6 +1378,9 @@ int mem_buf_get_fd(void *membuf_desc) int fd; struct mem_buf_desc *membuf = membuf_desc; + if (!membuf_desc) + return -EINVAL; + fd = get_unused_fd_flags(O_CLOEXEC); if (fd < 0) return fd; @@ -1486,16 +1504,11 @@ out: return ret; } -static bool is_valid_mem_type(enum mem_buf_mem_type mem_type) -{ - return mem_type >= MEM_BUF_ION_MEM_TYPE && - mem_type < MEM_BUF_MAX_MEM_TYPE; -} - static int validate_ioctl_arg(struct mem_buf_alloc_ioctl_arg *allocation) { if (!allocation->size || !allocation->nr_acl_entries || !allocation->acl_list || + (allocation->nr_acl_entries > MEM_BUF_MAX_NR_ACL_ENTS) || !is_valid_mem_type(allocation->src_mem_type) || !is_valid_mem_type(allocation->dst_mem_type) || allocation->reserved0 || allocation->reserved1 || diff --git a/include/uapi/linux/mem-buf.h b/include/uapi/linux/mem-buf.h index 1567e2144018..025e1acd3bc8 100644 --- a/include/uapi/linux/mem-buf.h +++ b/include/uapi/linux/mem-buf.h @@ -31,6 +31,8 @@ enum mem_buf_mem_type { (MEM_BUF_PERM_FLAG_READ | MEM_BUF_PERM_FLAG_WRITE |\ MEM_BUF_PERM_FLAG_EXEC) +#define MEM_BUF_MAX_NR_ACL_ENTS 16 + /** * struct acl_entry: Represents the access control permissions for a VMID. * @vmid: The mem-buf VMID specifier associated with the VMID that will access