Received: by 2002:a05:6a10:5bc5:0:0:0:0 with SMTP id os5csp2827508pxb; Mon, 1 Nov 2021 02:39:24 -0700 (PDT) X-Google-Smtp-Source: ABdhPJw4Se2S5LgGGXHw3lQhU1M07FMJTnBbH1e9SoqfJuJss6xeZHSwssuAkgxsra01XpbHZ7xB X-Received: by 2002:a05:6602:3c2:: with SMTP id g2mr20557484iov.1.1635759564431; Mon, 01 Nov 2021 02:39:24 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1635759564; cv=none; d=google.com; s=arc-20160816; b=V3h8TC/TzGB6ojI2nnbqSr8HAiZGLNXM5yjHfaV5AaWcIFlAwTQiBhme5Yn4REBWOV ectwR0Mcs8YtD2p4UqMZ6IDT+dsNmxqLv4bSr/W2WbfyjJTWTIcx1eTrsNhaJpuWnN2L YtT0WlW8m9Z2031gQpiiZm1zKdUcvwy8ZgDMxo5Ca1QupzgaR7JtRK1g8jHR7X25+KZD cqtLJSNl6bLqt4JYeUy/UzDnbf/fs8uDgAiv98/2c8KRRsdTJYHMlv9sfvMwcidzHGCi +irj6cJ7n0UgcPLh2YfaWSAguBUYlZ+fzU56svWTilhimvlpQpL7XqT9EknrNCauutLK JYhw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=PPtYM2Fb6J77BibmN8b4ACFkDXUhOW4/0dK0DBYjmM0=; b=SnedG5D0HglV1aAITJel2IX+9+Bvp4hx7IWXqU6e1FDH0p4Jf8d3FUR++Vvppvhand cJR4CV+uTdcH8Puq+BCkMQklqua9qOBsoKR+XF7Jct0pbaM76zj8+TAXaq+fuLkHR+Uq Smyaa5G00QKamlpyDRNEwJ/SHU4BDQ60RU+B2RVEnZK82gLK0Xyyq2pCm3XCPtvQQyy7 hSs9WlDcqAgfhyr5SItQz+LGcttMh+u4+KusK9XoEopNLZp1HIV826LK+PdM/ak9SSxP fNh/gUke5b/t5rjPsseh2lVUo1Nvm9sQsAl9bf7OU7BZ4AzZjD6C6pX8kC0Dp/gTP3TI hQCA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=nYP4gxmM; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id t2si12719191jam.80.2021.11.01.02.39.10; Mon, 01 Nov 2021 02:39:24 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=nYP4gxmM; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233927AbhKAJku (ORCPT + 99 others); Mon, 1 Nov 2021 05:40:50 -0400 Received: from mail.kernel.org ([198.145.29.99]:43648 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233708AbhKAJhx (ORCPT ); Mon, 1 Nov 2021 05:37:53 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id 5ED0061357; Mon, 1 Nov 2021 09:26:56 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1635758816; bh=se536qyWgd+Saudg8JzNo5S9uEwyH7QnCMCSpXHPrBI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=nYP4gxmM6ef4wA5V8po0UEo265Hw4dQ7grLECdA8nhU0EAXO4n1O103t9YR1siq8u XhGGiJOWfjZtOraoJIwmxl30I+b6zno1S9GnWFx9Mz0xjnG/e5LLh4UQ6ygtDiCvDW JMqALk0tgULaRmTElTj2APpI7xx8ZhqMJxl/qKwA= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Ilja Van Sprundel , Dennis Dalessandro , Mike Marciniszyn , Jason Gunthorpe Subject: [PATCH 5.10 39/77] IB/qib: Protect from buffer overflow in struct qib_user_sdma_pkt fields Date: Mon, 1 Nov 2021 10:17:27 +0100 Message-Id: <20211101082520.103837486@linuxfoundation.org> X-Mailer: git-send-email 2.33.1 In-Reply-To: <20211101082511.254155853@linuxfoundation.org> References: <20211101082511.254155853@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Mike Marciniszyn commit d39bf40e55e666b5905fdbd46a0dced030ce87be upstream. Overflowing either addrlimit or bytes_togo can allow userspace to trigger a buffer overflow of kernel memory. Check for overflows in all the places doing math on user controlled buffers. Fixes: f931551bafe1 ("IB/qib: Add new qib driver for QLogic PCIe InfiniBand adapters") Link: https://lore.kernel.org/r/20211012175519.7298.77738.stgit@awfm-01.cornelisnetworks.com Reported-by: Ilja Van Sprundel Reviewed-by: Dennis Dalessandro Signed-off-by: Mike Marciniszyn Signed-off-by: Dennis Dalessandro Signed-off-by: Jason Gunthorpe Signed-off-by: Greg Kroah-Hartman --- drivers/infiniband/hw/qib/qib_user_sdma.c | 33 ++++++++++++++++++++---------- 1 file changed, 23 insertions(+), 10 deletions(-) --- a/drivers/infiniband/hw/qib/qib_user_sdma.c +++ b/drivers/infiniband/hw/qib/qib_user_sdma.c @@ -602,7 +602,7 @@ done: /* * How many pages in this iovec element? */ -static int qib_user_sdma_num_pages(const struct iovec *iov) +static size_t qib_user_sdma_num_pages(const struct iovec *iov) { const unsigned long addr = (unsigned long) iov->iov_base; const unsigned long len = iov->iov_len; @@ -658,7 +658,7 @@ static void qib_user_sdma_free_pkt_frag( static int qib_user_sdma_pin_pages(const struct qib_devdata *dd, struct qib_user_sdma_queue *pq, struct qib_user_sdma_pkt *pkt, - unsigned long addr, int tlen, int npages) + unsigned long addr, int tlen, size_t npages) { struct page *pages[8]; int i, j; @@ -722,7 +722,7 @@ static int qib_user_sdma_pin_pkt(const s unsigned long idx; for (idx = 0; idx < niov; idx++) { - const int npages = qib_user_sdma_num_pages(iov + idx); + const size_t npages = qib_user_sdma_num_pages(iov + idx); const unsigned long addr = (unsigned long) iov[idx].iov_base; ret = qib_user_sdma_pin_pages(dd, pq, pkt, addr, @@ -824,8 +824,8 @@ static int qib_user_sdma_queue_pkts(cons unsigned pktnw; unsigned pktnwc; int nfrags = 0; - int npages = 0; - int bytes_togo = 0; + size_t npages = 0; + size_t bytes_togo = 0; int tiddma = 0; int cfur; @@ -885,7 +885,11 @@ static int qib_user_sdma_queue_pkts(cons npages += qib_user_sdma_num_pages(&iov[idx]); - bytes_togo += slen; + if (check_add_overflow(bytes_togo, slen, &bytes_togo) || + bytes_togo > type_max(typeof(pkt->bytes_togo))) { + ret = -EINVAL; + goto free_pbc; + } pktnwc += slen >> 2; idx++; nfrags++; @@ -904,8 +908,7 @@ static int qib_user_sdma_queue_pkts(cons } if (frag_size) { - int tidsmsize, n; - size_t pktsize; + size_t tidsmsize, n, pktsize, sz, addrlimit; n = npages*((2*PAGE_SIZE/frag_size)+1); pktsize = struct_size(pkt, addr, n); @@ -923,14 +926,24 @@ static int qib_user_sdma_queue_pkts(cons else tidsmsize = 0; - pkt = kmalloc(pktsize+tidsmsize, GFP_KERNEL); + if (check_add_overflow(pktsize, tidsmsize, &sz)) { + ret = -EINVAL; + goto free_pbc; + } + pkt = kmalloc(sz, GFP_KERNEL); if (!pkt) { ret = -ENOMEM; goto free_pbc; } pkt->largepkt = 1; pkt->frag_size = frag_size; - pkt->addrlimit = n + ARRAY_SIZE(pkt->addr); + if (check_add_overflow(n, ARRAY_SIZE(pkt->addr), + &addrlimit) || + addrlimit > type_max(typeof(pkt->addrlimit))) { + ret = -EINVAL; + goto free_pbc; + } + pkt->addrlimit = addrlimit; if (tiddma) { char *tidsm = (char *)pkt + pktsize;