Commit 8a794b35 authored by Necip Fazil Yildiran's avatar Necip Fazil Yildiran Committed by Greg Kroah-Hartman

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

[ Upstream commit 8dfddfb7 ]

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: bdabad3e ("net: Add Qualcomm IPC router")
Reported-by: syzbot+f31428628ef672716ea8@syzkaller.appspotmail.com
Signed-off-by: default avatarNecip Fazil Yildiran <necip@google.com>
Reviewed-by: default avatarDmitry Vyukov <dvyukov@google.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent ad270a5a
...@@ -554,23 +554,25 @@ static void qrtr_port_remove(struct qrtr_sock *ipc) ...@@ -554,23 +554,25 @@ static void qrtr_port_remove(struct qrtr_sock *ipc)
*/ */
static int qrtr_port_assign(struct qrtr_sock *ipc, int *port) static int qrtr_port_assign(struct qrtr_sock *ipc, int *port)
{ {
u32 min_port;
int rc; int rc;
mutex_lock(&qrtr_port_lock); mutex_lock(&qrtr_port_lock);
if (!*port) { if (!*port) {
rc = idr_alloc(&qrtr_ports, ipc, min_port = QRTR_MIN_EPH_SOCKET;
QRTR_MIN_EPH_SOCKET, QRTR_MAX_EPH_SOCKET + 1, rc = idr_alloc_u32(&qrtr_ports, ipc, &min_port, QRTR_MAX_EPH_SOCKET, GFP_ATOMIC);
GFP_ATOMIC); if (!rc)
if (rc >= 0) *port = min_port;
*port = rc;
} else if (*port < QRTR_MIN_EPH_SOCKET && !capable(CAP_NET_ADMIN)) { } else if (*port < QRTR_MIN_EPH_SOCKET && !capable(CAP_NET_ADMIN)) {
rc = -EACCES; rc = -EACCES;
} else if (*port == QRTR_PORT_CTRL) { } 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 { } else {
rc = idr_alloc(&qrtr_ports, ipc, *port, *port + 1, GFP_ATOMIC); min_port = *port;
if (rc >= 0) rc = idr_alloc_u32(&qrtr_ports, ipc, &min_port, *port, GFP_ATOMIC);
*port = rc; if (!rc)
*port = min_port;
} }
mutex_unlock(&qrtr_port_lock); mutex_unlock(&qrtr_port_lock);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment