···354354 return ret;355355}356356357357+static int param_from_user_memref(struct tee_context *ctx,358358+ struct tee_param_memref *memref,359359+ struct tee_ioctl_param *ip)360360+{361361+ struct tee_shm *shm;362362+363363+ /*364364+ * If a NULL pointer is passed to a TA in the TEE,365365+ * the ip.c IOCTL parameters is set to TEE_MEMREF_NULL366366+ * indicating a NULL memory reference.367367+ */368368+ if (ip->c != TEE_MEMREF_NULL) {369369+ /*370370+ * If we fail to get a pointer to a shared371371+ * memory object (and increase the ref count)372372+ * from an identifier we return an error. All373373+ * pointers that has been added in params have374374+ * an increased ref count. It's the callers375375+ * responibility to do tee_shm_put() on all376376+ * resolved pointers.377377+ */378378+ shm = tee_shm_get_from_id(ctx, ip->c);379379+ if (IS_ERR(shm))380380+ return PTR_ERR(shm);381381+382382+ /*383383+ * Ensure offset + size does not overflow384384+ * offset and does not overflow the size of385385+ * the referred shared memory object.386386+ */387387+ if ((ip->a + ip->b) < ip->a ||388388+ (ip->a + ip->b) > shm->size) {389389+ tee_shm_put(shm);390390+ return -EINVAL;391391+ }392392+ } else if (ctx->cap_memref_null) {393393+ /* Pass NULL pointer to OP-TEE */394394+ shm = NULL;395395+ } else {396396+ return -EINVAL;397397+ }398398+399399+ memref->shm_offs = ip->a;400400+ memref->size = ip->b;401401+ memref->shm = shm;402402+403403+ return 0;404404+}405405+357406static int params_from_user(struct tee_context *ctx, struct tee_param *params,358407 size_t num_params,359408 struct tee_ioctl_param __user *uparams)···410361 size_t n;411362412363 for (n = 0; n < num_params; n++) {413413- struct tee_shm *shm;414364 struct tee_ioctl_param ip;365365+ int rc;415366416367 if (copy_from_user(&ip, uparams + n, sizeof(ip)))417368 return -EFAULT;···434385 case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT:435386 case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_OUTPUT:436387 case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INOUT:437437- /*438438- * If a NULL pointer is passed to a TA in the TEE,439439- * the ip.c IOCTL parameters is set to TEE_MEMREF_NULL440440- * indicating a NULL memory reference.441441- */442442- if (ip.c != TEE_MEMREF_NULL) {443443- /*444444- * If we fail to get a pointer to a shared445445- * memory object (and increase the ref count)446446- * from an identifier we return an error. All447447- * pointers that has been added in params have448448- * an increased ref count. It's the callers449449- * responibility to do tee_shm_put() on all450450- * resolved pointers.451451- */452452- shm = tee_shm_get_from_id(ctx, ip.c);453453- if (IS_ERR(shm))454454- return PTR_ERR(shm);455455-456456- /*457457- * Ensure offset + size does not overflow458458- * offset and does not overflow the size of459459- * the referred shared memory object.460460- */461461- if ((ip.a + ip.b) < ip.a ||462462- (ip.a + ip.b) > shm->size) {463463- tee_shm_put(shm);464464- return -EINVAL;465465- }466466- } else if (ctx->cap_memref_null) {467467- /* Pass NULL pointer to OP-TEE */468468- shm = NULL;469469- } else {470470- return -EINVAL;471471- }472472-473473- params[n].u.memref.shm_offs = ip.a;474474- params[n].u.memref.size = ip.b;475475- params[n].u.memref.shm = shm;388388+ rc = param_from_user_memref(ctx, ¶ms[n].u.memref,389389+ &ip);390390+ if (rc)391391+ return rc;476392 break;477393 default:478394 /* Unknown attribute */