| From 578a1310f2592ba90c5674bca21c1dbd1adf3f0a Mon Sep 17 00:00:00 2001 |
| From: Zefan Li <lizefan@huawei.com> |
| Date: Wed, 26 Jun 2013 15:31:58 +0800 |
| Subject: dlci: validate the net device in dlci_del() |
| |
| From: Zefan Li <lizefan@huawei.com> |
| |
| commit 578a1310f2592ba90c5674bca21c1dbd1adf3f0a upstream. |
| |
| We triggered an oops while running trinity with 3.4 kernel: |
| |
| BUG: unable to handle kernel paging request at 0000000100000d07 |
| IP: [<ffffffffa0109738>] dlci_ioctl+0xd8/0x2d4 [dlci] |
| PGD 640c0d067 PUD 0 |
| Oops: 0000 [#1] PREEMPT SMP |
| CPU 3 |
| ... |
| Pid: 7302, comm: trinity-child3 Not tainted 3.4.24.09+ 40 Huawei Technologies Co., Ltd. Tecal RH2285 /BC11BTSA |
| RIP: 0010:[<ffffffffa0109738>] [<ffffffffa0109738>] dlci_ioctl+0xd8/0x2d4 [dlci] |
| ... |
| Call Trace: |
| [<ffffffff8137c5c3>] sock_ioctl+0x153/0x280 |
| [<ffffffff81195494>] do_vfs_ioctl+0xa4/0x5e0 |
| [<ffffffff8118354a>] ? fget_light+0x3ea/0x490 |
| [<ffffffff81195a1f>] sys_ioctl+0x4f/0x80 |
| [<ffffffff81478b69>] system_call_fastpath+0x16/0x1b |
| ... |
| |
| It's because the net device is not a dlci device. |
| |
| Reported-by: Li Jinyue <lijinyue@huawei.com> |
| Signed-off-by: Li Zefan <lizefan@huawei.com> |
| Signed-off-by: David S. Miller <davem@davemloft.net> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| drivers/net/wan/dlci.c | 12 ++++++++++++ |
| 1 file changed, 12 insertions(+) |
| |
| --- a/drivers/net/wan/dlci.c |
| +++ b/drivers/net/wan/dlci.c |
| @@ -384,6 +384,7 @@ static int dlci_del(struct dlci_add *dlc |
| struct frad_local *flp; |
| struct net_device *master, *slave; |
| int err; |
| + bool found = false; |
| |
| rtnl_lock(); |
| |
| @@ -393,6 +394,17 @@ static int dlci_del(struct dlci_add *dlc |
| err = -ENODEV; |
| goto out; |
| } |
| + |
| + list_for_each_entry(dlp, &dlci_devs, list) { |
| + if (dlp->master == master) { |
| + found = true; |
| + break; |
| + } |
| + } |
| + if (!found) { |
| + err = -ENODEV; |
| + goto out; |
| + } |
| |
| if (netif_running(master)) { |
| err = -EBUSY; |