IB/srpt: Verify port numbers in srpt_event_handler()
authorBart Van Assche <bart.vanassche@wdc.com>
Mon, 8 Jan 2018 19:00:45 +0000 (11:00 -0800)
committerDoug Ledford <dledford@redhat.com>
Mon, 8 Jan 2018 21:05:12 +0000 (16:05 -0500)
Verify whether port numbers are in the expected range before using
these as an array index. Complain if a port number is out of range.

Signed-off-by: Bart Van Assche <bart.vanassche@wdc.com>
Signed-off-by: Doug Ledford <dledford@redhat.com>
drivers/infiniband/ulp/srpt/ib_srpt.c

index a71664f..c5efe0a 100644 (file)
@@ -134,6 +134,7 @@ static void srpt_event_handler(struct ib_event_handler *handler,
 {
        struct srpt_device *sdev;
        struct srpt_port *sport;
+       u8 port_num;
 
        sdev = ib_get_client_data(event->device, &srpt_client);
        if (!sdev || sdev->device != event->device)
@@ -144,10 +145,15 @@ static void srpt_event_handler(struct ib_event_handler *handler,
 
        switch (event->event) {
        case IB_EVENT_PORT_ERR:
-               if (event->element.port_num <= sdev->device->phys_port_cnt) {
-                       sport = &sdev->port[event->element.port_num - 1];
+               port_num = event->element.port_num - 1;
+               if (port_num < sdev->device->phys_port_cnt) {
+                       sport = &sdev->port[port_num];
                        sport->lid = 0;
                        sport->sm_lid = 0;
+               } else {
+                       WARN(true, "event %d: port_num %d out of range 1..%d\n",
+                            event->event, port_num + 1,
+                            sdev->device->phys_port_cnt);
                }
                break;
        case IB_EVENT_PORT_ACTIVE:
@@ -157,15 +163,19 @@ static void srpt_event_handler(struct ib_event_handler *handler,
        case IB_EVENT_CLIENT_REREGISTER:
        case IB_EVENT_GID_CHANGE:
                /* Refresh port data asynchronously. */
-               if (event->element.port_num <= sdev->device->phys_port_cnt) {
-                       sport = &sdev->port[event->element.port_num - 1];
+               port_num = event->element.port_num - 1;
+               if (port_num < sdev->device->phys_port_cnt) {
+                       sport = &sdev->port[port_num];
                        if (!sport->lid && !sport->sm_lid)
                                schedule_work(&sport->work);
+               } else {
+                       WARN(true, "event %d: port_num %d out of range 1..%d\n",
+                            event->event, port_num + 1,
+                            sdev->device->phys_port_cnt);
                }
                break;
        default:
-               pr_err("received unrecognized IB event %d\n",
-                      event->event);
+               pr_err("received unrecognized IB event %d\n", event->event);
                break;
        }
 }