diff mbox series

[v2] net: qrtr: fix usage of idr in port assignment to socket

Message ID 20200817073900.3085391-1-fazilyildiran@gmail.com
State Superseded
Delegated to: David Miller
Headers show
Series [v2] net: qrtr: fix usage of idr in port assignment to socket | expand

Commit Message

Necip Fazil Yildiran Aug. 17, 2020, 7:39 a.m. UTC
From: Necip Fazil Yildiran <necip@google.com>

Passing large uint32 sockaddr_qrtr.port numbers for port allocation
triggers a warning within idr_alloc() since the port number is cast
to int, and thus interpreted as a negative number. This leads to
the rejection of such valid port numbers in qrtr_port_assign() as
idr_alloc() fails.

To avoid the problem, switch to idr_alloc_u32() instead.

Fixes: bdabad3e36 ("net: Add Qualcomm IPC router")
Reported-by: syzbot+f31428628ef672716ea8@syzkaller.appspotmail.com
Signed-off-by: Necip Fazil Yildiran <necip@google.com>
Reviewed-by: Dmitry Vyukov <dvyukov@google.com>
---
v2:
* Use reverse christmas tree ordering for local variables
* Add reviewed-by tag
---
 net/qrtr/qrtr.c | 20 +++++++++++---------
 1 file changed, 11 insertions(+), 9 deletions(-)

Comments

Jakub Kicinski Aug. 17, 2020, 3:29 p.m. UTC | #1
On Mon, 17 Aug 2020 07:39:01 +0000 Necip Fazil Yildiran wrote:
> From: Necip Fazil Yildiran <necip@google.com>
> 
> Passing large uint32 sockaddr_qrtr.port numbers for port allocation
> triggers a warning within idr_alloc() since the port number is cast
> to int, and thus interpreted as a negative number. This leads to
> the rejection of such valid port numbers in qrtr_port_assign() as
> idr_alloc() fails.
> 
> To avoid the problem, switch to idr_alloc_u32() instead.
> 
> Fixes: bdabad3e36 ("net: Add Qualcomm IPC router")
> Reported-by: syzbot+f31428628ef672716ea8@syzkaller.appspotmail.com
> Signed-off-by: Necip Fazil Yildiran <necip@google.com>
> Reviewed-by: Dmitry Vyukov <dvyukov@google.com>

Fixes tag: Fixes: bdabad3e36 ("net: Add Qualcomm IPC router")
Has these problem(s):
	- SHA1 should be at least 12 digits long
	  Can be fixed by setting core.abbrev to 12 (or more) or (for git v2.11
	  or later) just making sure it is not set (or set to "auto").
diff mbox series

Patch

diff --git a/net/qrtr/qrtr.c b/net/qrtr/qrtr.c
index b4c0db0b7d31..90c558f89d46 100644
--- a/net/qrtr/qrtr.c
+++ b/net/qrtr/qrtr.c
@@ -692,23 +692,25 @@  static void qrtr_port_remove(struct qrtr_sock *ipc)
  */
 static int qrtr_port_assign(struct qrtr_sock *ipc, int *port)
 {
+	u32 min_port;
 	int rc;
 
 	mutex_lock(&qrtr_port_lock);
 	if (!*port) {
-		rc = idr_alloc(&qrtr_ports, ipc,
-			       QRTR_MIN_EPH_SOCKET, QRTR_MAX_EPH_SOCKET + 1,
-			       GFP_ATOMIC);
-		if (rc >= 0)
-			*port = rc;
+		min_port = QRTR_MIN_EPH_SOCKET;
+		rc = idr_alloc_u32(&qrtr_ports, ipc, &min_port, QRTR_MAX_EPH_SOCKET, GFP_ATOMIC);
+		if (!rc)
+			*port = min_port;
 	} else if (*port < QRTR_MIN_EPH_SOCKET && !capable(CAP_NET_ADMIN)) {
 		rc = -EACCES;
 	} else if (*port == QRTR_PORT_CTRL) {
-		rc = idr_alloc(&qrtr_ports, ipc, 0, 1, GFP_ATOMIC);
+		min_port = 0;
+		rc = idr_alloc_u32(&qrtr_ports, ipc, &min_port, 0, GFP_ATOMIC);
 	} else {
-		rc = idr_alloc(&qrtr_ports, ipc, *port, *port + 1, GFP_ATOMIC);
-		if (rc >= 0)
-			*port = rc;
+		min_port = *port;
+		rc = idr_alloc_u32(&qrtr_ports, ipc, &min_port, *port, GFP_ATOMIC);
+		if (!rc)
+			*port = min_port;
 	}
 	mutex_unlock(&qrtr_port_lock);