Changeset 5723ae49 in mainline


Ignore:
Timestamp:
2011-11-06T23:24:30Z (13 years ago)
Author:
Jan Vesely <jano.vesely@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
e3e0953
Parents:
50f2095
Message:

usbhid: mouse: Fix error paths and a memory leak.

Remove useless functions: usb_mouse_new()/usb_mouse_destroy()
Free allocated data in init error paths.
Free buttons buffer in deinit.
Add range checks when accessing buttons buffer.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/drv/bus/usb/usbhid/mouse/mousedev.c

    r50f2095 r5723ae49  
    159159/*----------------------------------------------------------------------------*/
    160160
    161 static usb_mouse_t *usb_mouse_new(void)
    162 {
    163         usb_mouse_t *mouse = calloc(1, sizeof(usb_mouse_t));
    164         if (mouse == NULL) {
    165                 return NULL;
    166         }
    167         mouse->mouse_sess = NULL;
    168         mouse->wheel_sess = NULL;
    169         mouse->buttons = NULL;
    170         mouse->buttons_count = 0;
    171 
    172         return mouse;
    173 }
    174 
    175 /*----------------------------------------------------------------------------*/
    176 
    177 static void usb_mouse_destroy(usb_mouse_t *mouse_dev)
    178 {
    179         assert(mouse_dev != NULL);
    180 
    181         /* Hangup session to the console */
    182         if (mouse_dev->mouse_sess != NULL) {
    183                 const int ret = async_hangup(mouse_dev->mouse_sess);
    184                 if (ret != EOK)
    185                         usb_log_warning("Failed to hang up mouse session: "
    186                             "%p, %s.\n", mouse_dev->mouse_sess, str_error(ret));
    187         }
    188 
    189         if (mouse_dev->wheel_sess != NULL) {
    190                 const int ret = async_hangup(mouse_dev->wheel_sess);
    191                 if (ret != EOK)
    192                         usb_log_warning("Failed to hang up wheel session: "
    193                             "%p, %s.\n", mouse_dev->wheel_sess, str_error(ret));
    194         }
    195 
    196         int ret = ddf_fun_unbind(mouse_dev->mouse_fun);
    197         if (ret != EOK) {
    198                 usb_log_error("Failed to unbind mouse function.\n");
    199         } else {
    200                 ddf_fun_destroy(mouse_dev->mouse_fun);
    201                 /* Prevent double free, these two functions share driver data */
    202                 mouse_dev->wheel_fun->driver_data = NULL;
    203         }
    204 
    205         ret = ddf_fun_unbind(mouse_dev->wheel_fun);
    206         if (ret != EOK) {
    207                 usb_log_error("Failed to unbind wheel function.\n");
    208         } else {
    209                 ddf_fun_destroy(mouse_dev->wheel_fun);
    210         }
    211 
    212 }
    213 
    214 /*----------------------------------------------------------------------------*/
    215 
    216161static void usb_mouse_send_wheel(const usb_mouse_t *mouse_dev, int wheel)
    217162{
     
    306251                usb_log_debug2(NAME " VALUE(%X) USAGE(%X)\n", field->value,
    307252                    field->usage);
     253                assert(field->usage > field->usage_minimum);
     254                const unsigned index = field->usage - field->usage_minimum;
     255                assert(index < mouse_dev->buttons_count);
    308256               
    309                 if (mouse_dev->buttons[field->usage - field->usage_minimum] == 0
    310                     && field->value != 0) {
     257                if (mouse_dev->buttons[index] == 0 && field->value != 0) {
    311258                        async_exch_t *exch =
    312259                            async_exchange_begin(mouse_dev->mouse_sess);
     
    314261                        async_exchange_end(exch);
    315262                       
    316                         mouse_dev->buttons[field->usage - field->usage_minimum]
    317                             = field->value;
    318                 } else if (mouse_dev->buttons[field->usage - field->usage_minimum] != 0
    319                     && field->value == 0) {
     263                        mouse_dev->buttons[index] = field->value;
     264                } else if (mouse_dev->buttons[index] != 0 && field->value == 0) {
    320265                        async_exch_t *exch =
    321266                            async_exchange_begin(mouse_dev->mouse_sess);
     
    323268                        async_exchange_end(exch);
    324269
    325                         mouse_dev->buttons[field->usage - field->usage_minimum] =
    326                            field->value;
     270                        mouse_dev->buttons[index] = field->value;
    327271                }
    328272
     
    361305                usb_log_error("Could not bind DDF function: %s.\n",
    362306                    str_error(rc));
     307                fun->driver_data = NULL;
     308                ddf_fun_destroy(fun);
    363309                return rc;
    364310        }
     
    371317                    "Could not add DDF function to category %s: %s.\n",
    372318                    HID_MOUSE_CATEGORY, str_error(rc));
     319                ddf_fun_unbind(fun);
     320                fun->driver_data = NULL;
     321                ddf_fun_destroy(fun);
    373322                return rc;
    374323        }
     
    378327         * Special function for acting as keyboard (wheel)
    379328         */
    380         usb_log_debug("Creating DDF function %s...\n", 
     329        usb_log_debug("Creating DDF function %s...\n",
    381330                      HID_MOUSE_WHEEL_FUN_NAME);
    382         fun = ddf_fun_create(hid_dev->usb_dev->ddf_dev, fun_exposed, 
     331        fun = ddf_fun_create(hid_dev->usb_dev->ddf_dev, fun_exposed,
    383332            HID_MOUSE_WHEEL_FUN_NAME);
    384333        if (fun == NULL) {
    385334                usb_log_error("Could not create DDF function node.\n");
     335                ddf_fun_unbind(mouse->mouse_fun);
     336                mouse->mouse_fun->driver_data = NULL;
     337                ddf_fun_destroy(mouse->mouse_fun);
    386338                return ENOMEM;
    387339        }
     
    398350                usb_log_error("Could not bind DDF function: %s.\n",
    399351                    str_error(rc));
     352                ddf_fun_unbind(mouse->mouse_fun);
     353                mouse->mouse_fun->driver_data = NULL;
     354                ddf_fun_destroy(mouse->mouse_fun);
     355                fun->driver_data = NULL;
     356                ddf_fun_destroy(fun);
    400357                return rc;
    401358        }
     
    408365                    "Could not add DDF function to category %s: %s.\n",
    409366                    HID_MOUSE_WHEEL_CATEGORY, str_error(rc));
     367                ddf_fun_unbind(mouse->mouse_fun);
     368                mouse->mouse_fun->driver_data = NULL;
     369                ddf_fun_destroy(mouse->mouse_fun);
     370                ddf_fun_unbind(fun);
     371                fun->driver_data = NULL;
     372                ddf_fun_destroy(fun);
    410373                return rc;
    411374        }
     
    469432        }
    470433
    471         usb_mouse_t *mouse_dev = usb_mouse_new();
     434        usb_mouse_t *mouse_dev = calloc(1, sizeof(usb_mouse_t));
    472435        if (mouse_dev == NULL) {
    473436                usb_log_error("Error while creating USB/HID Mouse device "
     
    475438                return ENOMEM;
    476439        }
     440        mouse_dev->mouse_sess = NULL;
     441        mouse_dev->wheel_sess = NULL;
     442        mouse_dev->buttons = NULL;
     443        mouse_dev->buttons_count = 0;
    477444
    478445        // FIXME: This may not be optimal since stupid hardware vendor may
     
    492459        }
    493460
    494 
    495         // save the Mouse device structure into the HID device structure
    496         *data = mouse_dev;
    497 
    498461        // set handler for incoming calls
    499462        mouse_dev->ops.default_handler = default_connection_handler;
    500463
    501464        // TODO: how to know if the device supports the request???
    502         usbhid_req_set_idle(&hid_dev->usb_dev->ctrl_pipe, 
     465        usbhid_req_set_idle(&hid_dev->usb_dev->ctrl_pipe,
    503466            hid_dev->usb_dev->interface_no, IDLE_RATE);
    504467
    505468        int rc = usb_mouse_create_function(hid_dev, mouse_dev);
    506469        if (rc != EOK) {
    507                 usb_mouse_destroy(mouse_dev);
    508                 return rc;
    509         }
     470                free(mouse_dev->buttons);
     471                free(mouse_dev);
     472                return rc;
     473        }
     474
     475        /* Save the Mouse device structure into the HID device structure. */
     476        *data = mouse_dev;
    510477
    511478        return EOK;
     
    522489        }
    523490
    524         usb_mouse_t *mouse_dev = (usb_mouse_t *)data;
    525                
     491        usb_mouse_t *mouse_dev = data;
     492
    526493        return usb_mouse_process_report(hid_dev, mouse_dev);
    527494}
     
    531498void usb_mouse_deinit(usb_hid_dev_t *hid_dev, void *data)
    532499{
    533         if (data != NULL) {
    534                 usb_mouse_destroy(data);
    535         }
     500        if (data == NULL)
     501                return;
     502
     503        usb_mouse_t *mouse_dev = data;
     504
     505        /* Hangup session to the console */
     506        if (mouse_dev->mouse_sess != NULL) {
     507                const int ret = async_hangup(mouse_dev->mouse_sess);
     508                if (ret != EOK)
     509                        usb_log_warning("Failed to hang up mouse session: "
     510                            "%p, %s.\n", mouse_dev->mouse_sess, str_error(ret));
     511        }
     512
     513        if (mouse_dev->wheel_sess != NULL) {
     514                const int ret = async_hangup(mouse_dev->wheel_sess);
     515                if (ret != EOK)
     516                        usb_log_warning("Failed to hang up wheel session: "
     517                            "%p, %s.\n", mouse_dev->wheel_sess, str_error(ret));
     518        }
     519
     520        /* We might be called before being completely initialized */
     521        if (mouse_dev->mouse_fun) {
     522                const int ret = ddf_fun_unbind(mouse_dev->mouse_fun);
     523                if (ret != EOK) {
     524                        usb_log_error("Failed to unbind mouse function.\n");
     525                } else {
     526                        /* driver_data(mouse_dev) will be freed explicitly */
     527                        mouse_dev->mouse_fun->driver_data = NULL;
     528                        ddf_fun_destroy(mouse_dev->mouse_fun);
     529                }
     530        }
     531
     532        /* We might be called before being completely initialized */
     533        if (mouse_dev->mouse_fun) {
     534                const int ret = ddf_fun_unbind(mouse_dev->wheel_fun);
     535                if (ret != EOK) {
     536                        usb_log_error("Failed to unbind wheel function.\n");
     537                } else {
     538                        /* driver_data(mouse_dev) will be freed explicitly */
     539                        mouse_dev->wheel_fun->driver_data = NULL;
     540                        ddf_fun_destroy(mouse_dev->wheel_fun);
     541                }
     542        }
     543        free(mouse_dev->buttons);
     544        free(mouse_dev);
    536545}
    537546
Note: See TracChangeset for help on using the changeset viewer.