aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGuenter Roeck <linux@roeck-us.net>2016-11-09 22:51:25 -0500
committerDavid S. Miller <davem@davemloft.net>2016-11-13 12:03:20 -0500
commitca0a75316dc62af92943761b1cc049e15c92eb09 (patch)
treefb28b2c3fe8309b3ae2188ccf8f605ceb54227f6
parent10b217681ddec4fa3ddb375bb188fec504523da4 (diff)
r8152: Fix error path in open function
If usb_submit_urb() called from the open function fails, the following crash may be observed. r8152 8-1:1.0 eth0: intr_urb submit failed: -19 ... r8152 8-1:1.0 eth0: v1.08.3 Unable to handle kernel paging request at virtual address 6b6b6b6b6b6b6b7b pgd = ffffffc0e7305000 [6b6b6b6b6b6b6b7b] *pgd=0000000000000000, *pud=0000000000000000 Internal error: Oops: 96000004 [#1] PREEMPT SMP ... PC is at notifier_chain_register+0x2c/0x58 LR is at blocking_notifier_chain_register+0x54/0x70 ... Call trace: [<ffffffc0002407f8>] notifier_chain_register+0x2c/0x58 [<ffffffc000240bdc>] blocking_notifier_chain_register+0x54/0x70 [<ffffffc00026991c>] register_pm_notifier+0x24/0x2c [<ffffffbffc183200>] rtl8152_open+0x3dc/0x3f8 [r8152] [<ffffffc000808000>] __dev_open+0xac/0x104 [<ffffffc0008082f8>] __dev_change_flags+0xb0/0x148 [<ffffffc0008083c4>] dev_change_flags+0x34/0x70 [<ffffffc000818344>] do_setlink+0x2c8/0x888 [<ffffffc0008199d4>] rtnl_newlink+0x328/0x644 [<ffffffc000819e98>] rtnetlink_rcv_msg+0x1a8/0x1d4 [<ffffffc0008373c8>] netlink_rcv_skb+0x68/0xd0 [<ffffffc000817990>] rtnetlink_rcv+0x2c/0x3c [<ffffffc000836d1c>] netlink_unicast+0x16c/0x234 [<ffffffc00083720c>] netlink_sendmsg+0x340/0x364 [<ffffffc0007e85d0>] sock_sendmsg+0x48/0x60 [<ffffffc0007e9c30>] SyS_sendto+0xe0/0x120 [<ffffffc0007e9cb0>] SyS_send+0x40/0x4c [<ffffffc000203e34>] el0_svc_naked+0x24/0x28 Clean up error handling to avoid registering the notifier if the open function is going to fail. Signed-off-by: Guenter Roeck <linux@roeck-us.net> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/usb/r8152.c17
1 files changed, 10 insertions, 7 deletions
diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
index 75c516889645..efb84f092492 100644
--- a/drivers/net/usb/r8152.c
+++ b/drivers/net/usb/r8152.c
@@ -3266,10 +3266,8 @@ static int rtl8152_open(struct net_device *netdev)
3266 goto out; 3266 goto out;
3267 3267
3268 res = usb_autopm_get_interface(tp->intf); 3268 res = usb_autopm_get_interface(tp->intf);
3269 if (res < 0) { 3269 if (res < 0)
3270 free_all_mem(tp); 3270 goto out_free;
3271 goto out;
3272 }
3273 3271
3274 mutex_lock(&tp->control); 3272 mutex_lock(&tp->control);
3275 3273
@@ -3285,10 +3283,9 @@ static int rtl8152_open(struct net_device *netdev)
3285 netif_device_detach(tp->netdev); 3283 netif_device_detach(tp->netdev);
3286 netif_warn(tp, ifup, netdev, "intr_urb submit failed: %d\n", 3284 netif_warn(tp, ifup, netdev, "intr_urb submit failed: %d\n",
3287 res); 3285 res);
3288 free_all_mem(tp); 3286 goto out_unlock;
3289 } else {
3290 napi_enable(&tp->napi);
3291 } 3287 }
3288 napi_enable(&tp->napi);
3292 3289
3293 mutex_unlock(&tp->control); 3290 mutex_unlock(&tp->control);
3294 3291
@@ -3297,7 +3294,13 @@ static int rtl8152_open(struct net_device *netdev)
3297 tp->pm_notifier.notifier_call = rtl_notifier; 3294 tp->pm_notifier.notifier_call = rtl_notifier;
3298 register_pm_notifier(&tp->pm_notifier); 3295 register_pm_notifier(&tp->pm_notifier);
3299#endif 3296#endif
3297 return 0;
3300 3298
3299out_unlock:
3300 mutex_unlock(&tp->control);
3301 usb_autopm_put_interface(tp->intf);
3302out_free:
3303 free_all_mem(tp);
3301out: 3304out:
3302 return res; 3305 return res;
3303} 3306}