diff mbox

[4/4] linux-user: Fix error handling in target_to_host_semarray()

Message ID 1392663334-8555-5-git-send-email-peter.maydell@linaro.org
State Accepted
Headers show

Commit Message

Peter Maydell Feb. 17, 2014, 6:55 p.m. UTC
Fix two issues in error handling in target_to_host_semarray():
 * don't leak the host_array buffer if lock_user fails
 * return an error if malloc() fails

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 linux-user/syscall.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

Comments

Peter Maydell Feb. 18, 2014, 3:11 p.m. UTC | #1
On 18 February 2014 15:10, Riku Voipio <riku.voipio@iki.fi> wrote:
> On Mon, Feb 17, 2014 at 06:55:34PM +0000, Peter Maydell wrote:
>> Fix two issues in error handling in target_to_host_semarray():
>>  * don't leak the host_array buffer if lock_user fails
>>  * return an error if malloc() fails
>
> With this patch I get on ubuntu raring x86_64 (gcc 4.7):
>
> In function ‘target_to_host_semarray’,
>     inlined from ‘do_semctl’ at /home/voipio/linaro/qemu/linux-user/syscall.c:2502:17,
>     inlined from ‘do_syscall’ at /home/voipio/linaro/qemu/linux-user/syscall.c:6917:13:
> /home/voipio/linaro/qemu/linux-user/syscall.c:2439:13: error: attempt to free a non-heap object ‘array’ [-Werror=free-nonheap-object]
> cc1: all warnings being treated as errors

Doh. Missing '*':

>>
>>      *host_array = malloc(nsems*sizeof(unsigned short));
>> +    if (!*host_array) {
>> +        return -TARGET_ENOMEM;
>> +    }
>>      array = lock_user(VERIFY_READ, target_addr,
>>                        nsems*sizeof(unsigned short), 1);
>> -    if (!array)
>> +    if (!array) {
>> +        free(host_array);

...should be
    free(*host_array);

thanks
-- PMM
diff mbox

Patch

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index bb3e4b1..c92f026 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -2429,10 +2429,15 @@  static inline abi_long target_to_host_semarray(int semid, unsigned short **host_
     nsems = semid_ds.sem_nsems;
 
     *host_array = malloc(nsems*sizeof(unsigned short));
+    if (!*host_array) {
+        return -TARGET_ENOMEM;
+    }
     array = lock_user(VERIFY_READ, target_addr,
                       nsems*sizeof(unsigned short), 1);
-    if (!array)
+    if (!array) {
+        free(host_array);
         return -TARGET_EFAULT;
+    }
 
     for(i=0; i<nsems; i++) {
         __get_user((*host_array)[i], &array[i]);