From f65d70360f2fca923edca4afa7d4a88c7d947164 Mon Sep 17 00:00:00 2001 From: Ben Fennema Date: Tue, 25 Jul 2023 14:24:50 -0700 Subject: Fix memory leak in compat adsprpc ioctl's Bug: 287391584 Signed-off-by: Ben Fennema (cherry picked from https://partner-android-review.googlesource.com/q/commit:ef69bb7ab576818344b5e1437b388e96ea90ae84) Merged-In: I287ba154fbf95a1484b0f6021dcdefe4201b7f5f Change-Id: I287ba154fbf95a1484b0f6021dcdefe4201b7f5f --- drivers/char/adsprpc_compat.c | 90 ++++++++++++++++++++++++++++++++----------- 1 file changed, 67 insertions(+), 23 deletions(-) diff --git a/drivers/char/adsprpc_compat.c b/drivers/char/adsprpc_compat.c index bb06400b99af..5772ede885d4 100644 --- a/drivers/char/adsprpc_compat.c +++ b/drivers/char/adsprpc_compat.c @@ -344,10 +344,13 @@ static int compat_fastrpc_ioctl_invoke(struct file *filp, return -EFAULT; VERIFY(err, 0 == compat_get_fastrpc_ioctl_invoke(inv32, inv, cmd, sc)); - if (err) + if (err) { + kfree(inv); return err; + } VERIFY(err, 0 == (err = fastrpc_internal_invoke(fl, fl->mode, USER_MSG, inv))); + kfree(inv); return err; } @@ -399,8 +402,10 @@ static int compat_get_fastrpc_ioctl_invoke2( lasync32_old = compat_ptr(pparam); VERIFY(err, 0 == compat_get_fastrpc_ioctl_invoke(lasync32, asyncinv_user, COMPAT_FASTRPC_IOCTL_INVOKE_CRC, sc)); - if (err) + if (err) { + kfree(inv2_user); goto bail; + } asyncinv_user->job = NULL; err |= get_user(p, &lasync32_old->job); @@ -411,13 +416,13 @@ static int compat_get_fastrpc_ioctl_invoke2( VERIFY(err, 0 == compat_get_fastrpc_ioctl_invoke(lasync32, asyncinv_user, req, sc)); } - if (err) + if (err) { + kfree(inv2_user); goto bail; + } memcpy(&inv2_user->req, &req, sizeof(req)); inv2_user->invparam = (uintptr_t)asyncinv_user; inv2_user->size = sizeof(*asyncinv_user); - if (err) - goto bail; break; } case FASTRPC_INVOKE2_ASYNC_RESPONSE: @@ -457,8 +462,6 @@ static int compat_get_fastrpc_ioctl_invoke2( memcpy(&inv2_user->req, &req, sizeof(req)); memcpy(&inv2_user->invparam, &pparam, sizeof(pparam)); memcpy(&inv2_user->size, &size, sizeof(size)); - if (err) - goto bail; break; } default: @@ -474,7 +477,7 @@ static int compat_fastrpc_ioctl_invoke2(struct file *filp, unsigned int cmd, unsigned long arg) { struct compat_fastrpc_ioctl_invoke2 __user *inv32; - struct fastrpc_ioctl_invoke2 *inv; + struct fastrpc_ioctl_invoke2 *inv = NULL; int err = 0; struct fastrpc_file *fl = (struct fastrpc_file *)filp->private_data; @@ -485,6 +488,7 @@ static int compat_fastrpc_ioctl_invoke2(struct file *filp, return err; VERIFY(err, 0 == (err = fastrpc_internal_invoke2(fl, inv))); + kfree(inv); return err; } @@ -750,18 +754,25 @@ static int compat_fastrpc_control(struct fastrpc_file *fl, return -EFAULT; VERIFY(err, 0 == compat_get_fastrpc_ioctl_control(ctrl32, ctrl)); - if (err) + if (err) { + kfree(ctrl); return err; + } VERIFY(err, 0 == (err = fastrpc_internal_control(fl, ctrl))); - if (err) + if (err) { + kfree(ctrl); return err; + } err = get_user(p, &ctrl32->req); - if (err) + if (err) { + kfree(ctrl); return err; + } if (p == FASTRPC_CONTROL_KALLOC) { memcpy(&p, &ctrl->kalloc.kalloc_support, sizeof(ctrl->kalloc.kalloc_support)); err |= put_user(p, &ctrl32->kalloc.kalloc_support); } + kfree(ctrl); return err; } @@ -780,21 +791,28 @@ static int compat_fastrpc_get_dsp_info(struct fastrpc_file *fl, return -EFAULT; err = get_user(u, &info32->domain); - if (err) + if (err) { + kfree(info); return err; + } memcpy(&info->domain, &u, sizeof(info->domain)); err = get_user(u, &info32->attribute_ID); - if (err) + if (err) { + kfree(info); return err; + } memcpy(&info->attribute_ID, &u, sizeof(info->attribute_ID)); err = fastrpc_get_info_from_kernel(info, fl); - if (err) + if (err) { + kfree(info); return err; + } err = compat_put_fastrpc_ioctl_get_dsp_info(info32, info); + kfree(info); return err; } @@ -816,14 +834,19 @@ static inline long compat_fastrpc_mmap_device_ioctl(struct fastrpc_file *fl, return -EFAULT; err = compat_get_fastrpc_ioctl_mem_map(map32, map); - if (err) + if (err) { + kfree(map); return err; + } VERIFY(err, 0 == (err = fastrpc_internal_mem_map(fl, map))); - if (err) + if (err) { + kfree(map); return err; + } VERIFY(err, 0 == compat_put_fastrpc_ioctl_mem_map(map32, map)); + kfree(map); return err; } case COMPAT_FASTRPC_IOCTL_MEM_UNMAP: @@ -837,11 +860,14 @@ static inline long compat_fastrpc_mmap_device_ioctl(struct fastrpc_file *fl, return -EFAULT; err = compat_get_fastrpc_ioctl_mem_unmap(unmap32, unmap); - if (err) + if (err) { + kfree(unmap); return err; + } VERIFY(err, 0 == (err = fastrpc_internal_mem_unmap(fl, unmap))); + kfree(unmap); return err; } case COMPAT_FASTRPC_IOCTL_MMAP: @@ -855,12 +881,15 @@ static inline long compat_fastrpc_mmap_device_ioctl(struct fastrpc_file *fl, if (err) return -EFAULT; VERIFY(err, 0 == compat_get_fastrpc_ioctl_mmap(map32, map)); - if (err) + if (err) { + kfree(map); return err; + } VERIFY(err, 0 == (err = fastrpc_internal_mmap(fl, map))); VERIFY(err, 0 == compat_put_fastrpc_ioctl_mmap(map32, map)); + kfree(map); return err; } case COMPAT_FASTRPC_IOCTL_MMAP_64: @@ -874,10 +903,13 @@ static inline long compat_fastrpc_mmap_device_ioctl(struct fastrpc_file *fl, if (err) return -EFAULT; VERIFY(err, 0 == compat_get_fastrpc_ioctl_mmap_64(map32, map)); - if (err) + if (err) { + kfree(map); return err; + } VERIFY(err, 0 == (err = fastrpc_internal_mmap(fl, map))); VERIFY(err, 0 == compat_put_fastrpc_ioctl_mmap_64(map32, map)); + kfree(map); return err; } case COMPAT_FASTRPC_IOCTL_MUNMAP: @@ -892,10 +924,13 @@ static inline long compat_fastrpc_mmap_device_ioctl(struct fastrpc_file *fl, return -EFAULT; VERIFY(err, 0 == compat_get_fastrpc_ioctl_munmap(unmap32, unmap)); - if (err) + if (err) { + kfree(unmap); return err; + } VERIFY(err, 0 == (err = fastrpc_internal_munmap(fl, unmap))); + kfree(unmap); return err; } default: @@ -999,11 +1034,14 @@ long compat_fastrpc_device_ioctl(struct file *filp, unsigned int cmd, return -EFAULT; VERIFY(err, 0 == compat_get_fastrpc_ioctl_munmap_64(unmap32, unmap)); - if (err) + if (err) { + kfree(unmap); return err; + } VERIFY(err, 0 == (err = fastrpc_internal_munmap(fl, unmap))); + kfree(unmap); return err; } case COMPAT_FASTRPC_IOCTL_INIT: @@ -1020,10 +1058,13 @@ long compat_fastrpc_device_ioctl(struct file *filp, unsigned int cmd, return -EFAULT; VERIFY(err, 0 == compat_get_fastrpc_ioctl_init(init32, init, cmd)); - if (err) + if (err) { + kfree(init); return err; + } VERIFY(err, 0 == (err = fastrpc_init_process(fl, init))); + kfree(init); return err; } @@ -1040,11 +1081,14 @@ long compat_fastrpc_device_ioctl(struct file *filp, unsigned int cmd, return -EFAULT; err = get_user(u, info32); memcpy(info, &u, sizeof(u)); - if (err) + if (err) { + kfree(info); return err; + } VERIFY(err, 0 == (err = fastrpc_get_info(fl, info))); memcpy(&u, info, sizeof(*info)); err |= put_user(u, info32); + kfree(info); return err; } case FASTRPC_IOCTL_SETMODE: -- cgit v1.2.3