lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite for Android: free password hash cracker in your pocket
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-ID: <1511793691-6325-1-git-send-email-amelie.delaunay@st.com>
Date:   Mon, 27 Nov 2017 15:41:31 +0100
From:   Amelie Delaunay <amelie.delaunay@...com>
To:     John Youn <johnyoun@...opsys.com>, Felipe Balbi <balbi@...nel.org>,
        "Greg Kroah-Hartman" <gregkh@...uxfoundation.org>
CC:     <linux-usb@...r.kernel.org>, <linux-kernel@...r.kernel.org>,
        "Amelie Delaunay" <amelie.delaunay@...com>
Subject: [PATCH] usb: dwc2: gadget: fix dwc2_check_param_tx_fifo_sizes

In case of OTG mode, with an OTG adapter plugged, the
dwc2_check_param_tx_fifo_sizes function reads DPTXFSIZN registers while
the controller is in Host mode, and, because DPTXFSIZN registers are
Device specific registers, the values read are 0.
Then, g_tx_fifo_size[fifo] values are considered invalid because in the
comparison test, they need to be greater than min and lower than dptxfszn
which is 0.
To fix this issue, force the controller in device mode if needed before
reading the DPTXFSIZN registers, and restore the previous mode if needed
after reading.

Fixes: 3c6aea7344c3 ("usb: dwc2: gadget: Add checking for g-tx-fifo-size
parameter")
Signed-off-by: Amelie Delaunay <amelie.delaunay@...com>
---
 drivers/usb/dwc2/params.c | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/drivers/usb/dwc2/params.c b/drivers/usb/dwc2/params.c
index ef73af6..302fefb 100644
--- a/drivers/usb/dwc2/params.c
+++ b/drivers/usb/dwc2/params.c
@@ -469,6 +469,7 @@ static void dwc2_check_param_tx_fifo_sizes(struct dwc2_hsotg *hsotg)
 	int fifo;
 	int min;
 	u32 total = 0;
+	bool forced;
 	u32 dptxfszn;
 
 	fifo_count = dwc2_hsotg_tx_fifo_count(hsotg);
@@ -483,6 +484,12 @@ static void dwc2_check_param_tx_fifo_sizes(struct dwc2_hsotg *hsotg)
 		dwc2_set_param_tx_fifo_sizes(hsotg);
 	}
 
+	/*
+	 * Reading DPTXFSIZN registers requires the controller to be in device
+	 * mode. The mode will be forced, if necessary, to read these values.
+	 */
+	forced = dwc2_force_mode_if_needed(hsotg, false);
+
 	for (fifo = 1; fifo <= fifo_count; fifo++) {
 		dptxfszn = (dwc2_readl(hsotg->regs + DPTXFSIZN(fifo)) &
 			FIFOSIZE_DEPTH_MASK) >> FIFOSIZE_DEPTH_SHIFT;
@@ -495,6 +502,9 @@ static void dwc2_check_param_tx_fifo_sizes(struct dwc2_hsotg *hsotg)
 			hsotg->params.g_tx_fifo_size[fifo] = dptxfszn;
 		}
 	}
+
+	if (forced)
+		dwc2_clear_force_mode(hsotg);
 }
 
 #define CHECK_RANGE(_param, _min, _max, _def) do {			\
-- 
2.7.4

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ