> Hi,
> I put here a bug among others:
> 
> -------------------------- dev/sdmmc/sdmmc.c --------------------------
> 
> 783                   data = malloc(ucmd->c_datalen, M_TEMP,
>                           M_WAITOK | M_CANFAIL);
>                       if (data == NULL)
>                               return ENOMEM;
>                       if (copyin(ucmd->c_data, data, ucmd->c_datalen))
>                               return EFAULT;
> 
> -----------------------------------------------------------------------
> 
> 'data' is leaked.

This ought to fix this problem:

Index: sdmmc.c
===================================================================
RCS file: /cvs/src/sys/dev/sdmmc/sdmmc.c,v
retrieving revision 1.36
diff -u -p -r1.36 sdmmc.c
--- sdmmc.c     1 Nov 2014 16:32:06 -0000       1.36
+++ sdmmc.c     15 Feb 2015 20:52:08 -0000
@@ -749,7 +749,7 @@ sdmmc_ioctl(struct device *self, u_long 
        struct sdmmc_command *ucmd;
        struct sdmmc_command cmd;
        void *data;
-       int error;
+       int error = 0;
 
        switch (request) {
 #ifdef SDMMC_DEBUG
@@ -784,8 +784,9 @@ sdmmc_ioctl(struct device *self, u_long 
                            M_WAITOK | M_CANFAIL);
                        if (data == NULL)
                                return ENOMEM;
-                       if (copyin(ucmd->c_data, data, ucmd->c_datalen))
-                               return EFAULT;
+                       error = copyin(ucmd->c_data, data, ucmd->c_datalen);
+                       if (error != 0)
+                               goto exec_done;
 
                        cmd.c_data = data;
                        cmd.c_datalen = ucmd->c_datalen;
@@ -804,10 +805,10 @@ sdmmc_ioctl(struct device *self, u_long 
                ucmd->c_flags = cmd.c_flags;
                ucmd->c_error = cmd.c_error;
 
-               if (ucmd->c_data && copyout(data, ucmd->c_data,
-                   ucmd->c_datalen))
-                       return EFAULT;
+               if (ucmd->c_data)
+                      error = copyout(data, ucmd->c_data, ucmd->c_datalen);
 
+exec_done:
                if (ucmd->c_data)
                        free(data, M_TEMP, 0);
                break;
@@ -815,7 +816,7 @@ sdmmc_ioctl(struct device *self, u_long 
        default:
                return ENOTTY;
        }
-       return 0;
+       return error;
 }
 #endif
 

Reply via email to