net: qrtr: Fix an out of bounds read qrtr_endpoint_post()
authorDan Carpenter <dan.carpenter@oracle.com>
Tue, 30 Jun 2020 11:46:15 +0000 (14:46 +0300)
committerDavid S. Miller <davem@davemloft.net>
Wed, 1 Jul 2020 01:36:13 +0000 (18:36 -0700)
This code assumes that the user passed in enough data for a
qrtr_hdr_v1 or qrtr_hdr_v2 struct, but it's not necessarily true.  If
the buffer is too small then it will read beyond the end.

Reported-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
Reported-by: syzbot+b8fe393f999a291a9ea6@syzkaller.appspotmail.com
Fixes: 194ccc88297a ("net: qrtr: Support decoding incoming v2 packets")
Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/qrtr/qrtr.c

index 0598813..24a8c3c 100644 (file)
@@ -429,7 +429,7 @@ int qrtr_endpoint_post(struct qrtr_endpoint *ep, const void *data, size_t len)
        unsigned int ver;
        size_t hdrlen;
 
-       if (len & 3)
+       if (len == 0 || len & 3)
                return -EINVAL;
 
        skb = netdev_alloc_skb(NULL, len);
@@ -443,6 +443,8 @@ int qrtr_endpoint_post(struct qrtr_endpoint *ep, const void *data, size_t len)
 
        switch (ver) {
        case QRTR_PROTO_VER_1:
+               if (len < sizeof(*v1))
+                       goto err;
                v1 = data;
                hdrlen = sizeof(*v1);
 
@@ -456,6 +458,8 @@ int qrtr_endpoint_post(struct qrtr_endpoint *ep, const void *data, size_t len)
                size = le32_to_cpu(v1->size);
                break;
        case QRTR_PROTO_VER_2:
+               if (len < sizeof(*v2))
+                       goto err;
                v2 = data;
                hdrlen = sizeof(*v2) + v2->optlen;