| From 2a3d9cce7fae80a89d53aaa91a48e1877222a619 Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Sat, 3 Aug 2019 20:29:04 -0400 |
| Subject: ath6kl: fix a NULL-ptr-deref bug in ath6kl_usb_alloc_urb_from_pipe() |
| |
| From: Hui Peng <benquike@gmail.com> |
| |
| [ Upstream commit 39d170b3cb62ba98567f5c4f40c27b5864b304e5 ] |
| |
| The `ar_usb` field of `ath6kl_usb_pipe_usb_pipe` objects |
| are initialized to point to the containing `ath6kl_usb` object |
| according to endpoint descriptors read from the device side, as shown |
| below in `ath6kl_usb_setup_pipe_resources`: |
| |
| for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) { |
| endpoint = &iface_desc->endpoint[i].desc; |
| |
| // get the address from endpoint descriptor |
| pipe_num = ath6kl_usb_get_logical_pipe_num(ar_usb, |
| endpoint->bEndpointAddress, |
| &urbcount); |
| ...... |
| // select the pipe object |
| pipe = &ar_usb->pipes[pipe_num]; |
| |
| // initialize the ar_usb field |
| pipe->ar_usb = ar_usb; |
| } |
| |
| The driver assumes that the addresses reported in endpoint |
| descriptors from device side to be complete. If a device is |
| malicious and does not report complete addresses, it may trigger |
| NULL-ptr-deref `ath6kl_usb_alloc_urb_from_pipe` and |
| `ath6kl_usb_free_urb_to_pipe`. |
| |
| This patch fixes the bug by preventing potential NULL-ptr-deref |
| (CVE-2019-15098). |
| |
| Signed-off-by: Hui Peng <benquike@gmail.com> |
| Reported-by: Hui Peng <benquike@gmail.com> |
| Reported-by: Mathias Payer <mathias.payer@nebelwelt.net> |
| Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| drivers/net/wireless/ath/ath6kl/usb.c | 8 ++++++++ |
| 1 file changed, 8 insertions(+) |
| |
| diff --git a/drivers/net/wireless/ath/ath6kl/usb.c b/drivers/net/wireless/ath/ath6kl/usb.c |
| index 4defb7a0330f4..53b66e9434c99 100644 |
| --- a/drivers/net/wireless/ath/ath6kl/usb.c |
| +++ b/drivers/net/wireless/ath/ath6kl/usb.c |
| @@ -132,6 +132,10 @@ ath6kl_usb_alloc_urb_from_pipe(struct ath6kl_usb_pipe *pipe) |
| struct ath6kl_urb_context *urb_context = NULL; |
| unsigned long flags; |
| |
| + /* bail if this pipe is not initialized */ |
| + if (!pipe->ar_usb) |
| + return NULL; |
| + |
| spin_lock_irqsave(&pipe->ar_usb->cs_lock, flags); |
| if (!list_empty(&pipe->urb_list_head)) { |
| urb_context = |
| @@ -150,6 +154,10 @@ static void ath6kl_usb_free_urb_to_pipe(struct ath6kl_usb_pipe *pipe, |
| { |
| unsigned long flags; |
| |
| + /* bail if this pipe is not initialized */ |
| + if (!pipe->ar_usb) |
| + return; |
| + |
| spin_lock_irqsave(&pipe->ar_usb->cs_lock, flags); |
| pipe->urb_cnt++; |
| |
| -- |
| 2.20.1 |
| |