From nobody Sun May 24 18:41:33 2026 Received: from mail-pf1-f179.google.com (mail-pf1-f179.google.com [209.85.210.179]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 59F3A2AD37 for ; Sun, 24 May 2026 06:07:02 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.210.179 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779602824; cv=none; b=D/lC0ZW1E/1Nxu74k5ar+Au6ovrihH92hI2UAE2QtR4oo1vPeTgEr097W1zi/0Q8tQK/sEYrFvOzv/yb58a0MdQlBdckLpJG6YW9aWaKSSLD0Q1+X3j4YAu5aQbTAPu9HjtWl9EzWT8csgLXjEj3NJ4kIhgDL3Aa7gX0SOFe0V0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779602824; c=relaxed/simple; bh=v3I0u2k/rCVGOjSflorBQS4WOY5BswCuWl7YrCNKfDs=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=e/ezCloHLsLVQsX8tIPqm8HwlHwM7oTLsw18wuj+aXy9R2mJoj5ar/spaObDjqOj1OU1bdOkmB7mZ7IWa78c3h+MQHKxLFaZhj2zQAolJslvQboeKAEIQvU9ky6m9mmW6G8kVNyOyXx15GjBraKyinXnQTlr4Ott4E4XxaOAxDY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=cBGYHTHT; arc=none smtp.client-ip=209.85.210.179 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="cBGYHTHT" Received: by mail-pf1-f179.google.com with SMTP id d2e1a72fcca58-8353c9f24d2so4356519b3a.3 for ; Sat, 23 May 2026 23:07:02 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1779602822; x=1780207622; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=C/5rmJ0MMc9nuHByS4ezujVFP1BbYR7lj+NuMOXCZLY=; b=cBGYHTHTyuzLy/iNpM3kmMi6TjeQjt88qjwx8f+dtv+Vai/0O+m0t++J764SI8JRvM 427QU5tq8vaABuzuMmeaGNiS3fCEuulVNHherw7rTGv5MtkyWS127X5vygyFn0ASP4Sx mhnq4UPCGvqg/CAsM66k4P5apOOEtIzumsi/RvJ3SRkulM30paJnuTl2NHBoMRtL+3m0 wchLYZaz6Rcoy9cFXFMRvFQ9wwXjxXSwGtGRdLARbGEs/+HhwZIGWuzrd6f/kQ1xBY58 XnNcnxBy/pWEYUnGV5Uyi9x/k/irv3Ly5jITJO9EvWfEtwQ+TDKq0YU5EXhG2o92kVvI ns8w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1779602822; x=1780207622; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=C/5rmJ0MMc9nuHByS4ezujVFP1BbYR7lj+NuMOXCZLY=; b=jnvJUMz5UW+j+/IJOorG1nCYDDSYE2S+K+gHnr2j+dkO+FuS0IPvHURPvfM4GTGP8g 38o57j1vCsSt2dGzul8HeVrWXe7T+XaYZHoklTal1efvpWyxkbcPpdsRVbiH7w+xeglA TTt8T8iQ16YoTAHWFt1Qedo8w0ExGuujyhqba4FRdyE/+RDyluHH6O/aYcb6CuuKG8oD B7rB2HEG6K8nt1otYjM4KB94HzerGIWFQ5KIaeuyT0miOi9kgGpFdvgjwXkce/MHxCjn qcyhb1mTW9Av5di2lNxdBLw0gPzq5tmxqcajAe8z6IANu8wK0zxwTM9xEuQLUeTHQWkx oy5A== X-Forwarded-Encrypted: i=1; AFNElJ+xo4+Q4V3JhLiG4NrWcvIWKvKF/HuXsI8opO9DeLOto32dhv44aJ45IvefHsDHmUW8FKD68fMXvKyAwuE=@vger.kernel.org X-Gm-Message-State: AOJu0Yx2X3Y+JzpWvRRl+x5OHn9f4lfChQG+V7CjhxbzTRkGhRfuM+fg BDCxccKbCGfdd8LH6bcSXYQD5/sLAvXo01k5jujzGA1BWcvGH+/NATjc X-Gm-Gg: Acq92OG397/y1bFneae1n+pVxk6HlanQyXjsiiQpSgocpEFahFwjKClWpqzNYa+mw4B skDchDcy7uFYSiNV4gObmxSZwQRFvSWQMFsOEJeLY5iWnQCnViyArqvZBJ0l+7EAYqnStSahUPb IlJESZsUpifSmMeDUiclGjQFO3I/9GrC3fS3u6Vg3Tu3lAadfV57wU2R14ltM4Z6Sly0NRb1kI0 AE7TBMKRrtTtKlFuG/ynbmgiFp7VJbU9farG5RXnf2Efu537+WCcAdSwSUlerR7hTZb8/sJgaqf 3b6Xa70EOLpN9Mj3Ov6j3SIjRWFwp5NaSFMQ1MHCQzd5ZlshCbETjmD3BWCSFG7e7hodoCcFyw0 PUOUd946LDIEDTu2ooEVyUWAsxk+nxlgYJYwbYXqWO6GTCXiuYDTdRVez9idsMA3znbGaIL1FLe DwLUbAOjw+xU09xW0Pm0jmUwgLXeL2ywi/GHqaBtwu4SXZY6/pkaLKo4kXAQgZrXW5A5SvdB7TN 9sL++RauXqy7Rz30NidlB0TMIQvE5BtGkGKpGbEmGK0S+d2Zt2Akzl1WWFAPrbh7KR0xogOrDeN nYIAxYA2dmSMQ89EbzhHkQ== X-Received: by 2002:aa7:9067:0:b0:834:efcb:12b4 with SMTP id d2e1a72fcca58-8415f406722mr9473675b3a.28.1779602821789; Sat, 23 May 2026 23:07:01 -0700 (PDT) Received: from codespaces-78f0a7.mimvmn1ww3huhhjmzljqefhnig.rx.internal.cloudapp.net ([4.240.39.196]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-84164fb00b6sm7310818b3a.40.2026.05.23.23.06.58 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 23 May 2026 23:07:01 -0700 (PDT) From: Muhammad Bilal To: robh@kernel.org Cc: tomeu@tomeuvizoso.net, ogabbay@kernel.org, tzimmermann@suse.de, Frank.Li@nxp.com, dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, stable@vger.kernel.org, Muhammad Bilal Subject: [PATCH v2] accel/ethosu: fix integer overflow and underflow in dma_length() Date: Sun, 24 May 2026 06:06:44 +0000 Message-ID: <20260524060644.106635-1-meatuni001@gmail.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260524051659.70654-1-meatuni001@gmail.com> References: <20260524051659.70654-1-meatuni001@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" dma_length() computes the total DMA transfer length as: len =3D ((len + stride[0]) * size0 + stride[1]) * size1 where len and stride[] are 64-bit values derived from user-supplied 40-bit command stream fields, and size0/size1 are user-supplied u16 values. Two bugs exist: 1. Integer overflow: the final multiplication by size1 (up to 65535) on an intermediate result that can already be ~2^55 easily exceeds 2^64, wrapping the u64 result to a small positive value. This wrapped value passes the region_size[i] <=3D gem->size check in ethosu_job.c while the hardware executes DMA with the original large strides, accessing memory outside the GEM buffer. 2. Negative stride underflow: stride[0] and stride[1] are signed 64-bit values sign-extended from 40-bit user input, and can be negative. Adding a large negative stride to a small u64 len wraps to a huge value. With size0 or size1 =3D=3D 1, check_mul_overflow() does not trigger, and len + offset can wrap back to a small value, bypassing the bounds check while the hardware accesses memory below the GEM buffer base. 3. Missing caller check: dma_length() returned U64_MAX on error but the caller only used the result for dev_dbg(), never checking for U64_MAX. This left info->region_size[] at 0, causing ethosu_job.c to skip the region entirely and allow hardware to run with stale physical addresses. Fix by adding underflow checks before each stride addition, replacing the unchecked multiplications with check_mul_overflow(), and adding a U64_MAX check in the caller that returns -EINVAL. Fixes: 5a5e9c0228e6 ("accel: Add Arm Ethos-U NPU driver") Cc: stable@vger.kernel.org Signed-off-by: Muhammad Bilal --- drivers/accel/ethosu/ethosu_gem.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/drivers/accel/ethosu/ethosu_gem.c b/drivers/accel/ethosu/ethos= u_gem.c index 5a02285a4986..0383b7a6c3d3 100644 --- a/drivers/accel/ethosu/ethosu_gem.c +++ b/drivers/accel/ethosu/ethosu_gem.c @@ -2,6 +2,7 @@ /* Copyright 2025 Arm, Ltd. */ =20 #include +#include #include =20 #include @@ -164,12 +165,18 @@ static u64 dma_length(struct ethosu_validated_cmdstre= am_info *info, u64 len =3D dma->len; =20 if (mode >=3D 1) { + if (dma->stride[0] < 0 && (u64)(-dma->stride[0]) > len) + return U64_MAX; len +=3D dma->stride[0]; - len *=3D dma_st->size0; + if (check_mul_overflow(len, (u64)dma_st->size0, &len)) + return U64_MAX; } if (mode =3D=3D 2) { + if (dma->stride[1] < 0 && (u64)(-dma->stride[1]) > len) + return U64_MAX; len +=3D dma->stride[1]; - len *=3D dma_st->size1; + if (check_mul_overflow(len, (u64)dma_st->size1, &len)) + return U64_MAX; } if (dma->region >=3D 0) info->region_size[dma->region] =3D max(info->region_size[dma->region], @@ -397,6 +404,8 @@ static int ethosu_gem_cmdstream_copy_and_validate(struc= t drm_device *ddev, case NPU_OP_DMA_START: srclen =3D dma_length(info, &st.dma, &st.dma.src); dstlen =3D dma_length(info, &st.dma, &st.dma.dst); + if (srclen =3D=3D U64_MAX || dstlen =3D=3D U64_MAX) + return -EINVAL; =20 if (st.dma.dst.region >=3D 0) info->output_region[st.dma.dst.region] =3D true; --=20 2.53.0