From nobody Mon Jun 8 06:36:45 2026 Received: from mail-pl1-f169.google.com (mail-pl1-f169.google.com [209.85.214.169]) (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 E59C037C902 for ; Mon, 1 Jun 2026 12:52:23 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.169 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780318345; cv=none; b=ayKBDDfEqYkh8YBdy9db4mb1rc0QUjhuQS52cAgxGitlWH0jfca5JWenSsRR4sOW5V07lKhsMDkMFvXI5kKoJzhchbCjJoPBgpB45WHJUBYIUgz9qW/37Hr5h1fBfSWbGDVWVeeiwVSpZYb/Gp8G8CzNsDoRPvrGzpTUnj3+d8Q= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780318345; c=relaxed/simple; bh=NcYkRwbTqa9/9wwiFQPeiIapfIns+vtyqJSwRf6t/TY=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=gF7zuuyNeRKtZdH58P5lTAC/lBnST2wja7QLkvEb/zgIktM2h6Se7amo9Q9FroAiQCKi2q2WxrwGYlvW9HsQPpWa6v8ZQw933HlaDeqa9m0XwWgPAy0F31YisDv8uuwPwWd86AUI7WpvRE17v58RLMde9OJAgg+1BnxT1xieVt8= 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=SpRpzCjP; arc=none smtp.client-ip=209.85.214.169 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="SpRpzCjP" Received: by mail-pl1-f169.google.com with SMTP id d9443c01a7336-2be1dd4af34so147577595ad.1 for ; Mon, 01 Jun 2026 05:52:23 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1780318343; x=1780923143; 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=JpFJ2vgllIWj4FqG6DXjRM527rlfnB9NVugM5813YTM=; b=SpRpzCjPVsdpO5mDITKcEAHGi+t2IDW90c6eDvEpM8zHXmFy6Px/QLuzywP1U3gLLE qO2wfeYBGIdtuN/AS5Jd1rWMRKgIFzntumbnOTAkzmdPS0VOvG9AimysflbjOOUsMgEi jB+NCGZtmB/RAKwN3XHbXBbmy3Rk/wRdG31WkkzzgBE6BkPuww5HoL0zXhhhN+kNd6GR OsawVNrkfvSm6em22nCKTdwrXqgs6t6XMyjLEeOlUXQuKsPW7CCObnwJZ2jGh+NeG0d/ 26yN0E4+/QMGb+/kZyWfoWa9ovtx4F2fjZVbs3wtzd+wwc1mCrjO/pYlzW/gCrkR0Wg6 jaAA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1780318343; x=1780923143; 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=JpFJ2vgllIWj4FqG6DXjRM527rlfnB9NVugM5813YTM=; b=oZyG+BYJvjt8reUl9H7rMxeCPr4eddOgop8UZ53tabgMAMPM0DtpD4Uw7duLm9WDLL CuQnupxfbWioxqROz8pC5hC4MdccdEE6aMKjYS4lPP859bKDvPSgOOtfm4sxrRhrCmsG bzPfVlpoLrkx3kR6+O0TAgXxLorpDsLN7JsWmNj+e4GA+ykwNQgaOck/SEd1Tz1I43Fc 0Nf4Ij0IIGzD5/N5/IPYsuJcYBrwSI5d9isVZRe7x9QxEgZxMH+Lp2r3Xm6rAJqztbFb EnqTyCtMp8HC76ujbAzad1WWV0DA5cjWRaeyt+ARndwoGSaExI92JX/t5Rj+UcgKZ0Sf 9uVQ== X-Forwarded-Encrypted: i=1; AFNElJ9tHDFnPZgLOfNEloClsm1Iv6kb/UwrvPO2ICKPvpDhMxJwj19N/BdWZqfO0jj2kqjI//GIF6u7ljk3sOk=@vger.kernel.org X-Gm-Message-State: AOJu0YyzgoJ7lbqWRqI8VlcgHHmaHJVj12qIn0X2XxIxqmQyZt1JSVgz t+DSxWCRJ+8arG6ZwkRPrhzphPSJ2Dj53J2n/NljvoZCEXpbiBUvVmC8JgfHDQi3 X-Gm-Gg: Acq92OERCXyoNSBCM2OfdYNImJ7S8cq4RJW817RsI9Q16nK6wHFUKUmgrZcmYQo6woS zhnTesPYw1oXIwu4as8bxOmslWXMGfYYePlFOW+y2YWK19XVWmV9bTvXrIUToy/5USKhpiSeisb dKfktH19qWoYU1BphR5R+DtdwtPnpdVR/XC/GsoZ4/GbhephvjsQZ7ZCD6RrTfrkP8lKPOlAK8g DbnsFD8cwxJZsTv5qkbNbSWncesQujYcyuqi1tDZHavmTJ8y6HDmztK/n7RsJ7fwTtVwDlvcYr4 X8KqVyi7DV8d3fKWZOnWjr74UtTjdf0bxxBSw1aBSDfX6hltDQAJB84v7+2AHjBJQs4dwZwTF3A z+GFxb3ThB+GMHA3SGDc9Sx7wqdALBwiretMCHv401zdBxDZwYBR9alUsq66vxxQ/AHZdcZxBrb nhDc3mw8dNlBJMy5b1UGsoWvysGXq7jpCAmnjLBSFXo+69+UuM4BxbC2SMsp+tSc4sBvc= X-Received: by 2002:a17:903:1905:b0:2bf:281f:19ec with SMTP id d9443c01a7336-2bf36803dccmr130037915ad.24.1780318342942; Mon, 01 Jun 2026 05:52:22 -0700 (PDT) Received: from LAPTOP-97G9G880.domain.name ([106.222.200.157]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-2bf7b6609f5sm85932415ad.60.2026.06.01.05.52.19 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 01 Jun 2026 05:52:22 -0700 (PDT) From: Karthikeyan KS To: andrew@codeconstruct.com.au Cc: joel@jms.id.au, andrew@aj.id.au, linux-arm-kernel@lists.infradead.org, linux-aspeed@lists.ozlabs.org, linux-kernel@vger.kernel.org, Karthikeyan KS , stable@vger.kernel.org Subject: [PATCH v4] soc: aspeed: lpc-snoop: Fix usercopy overflow in snoop_file_read Date: Mon, 1 Jun 2026 12:52:13 +0000 Message-ID: <20260601125214.2071019-1-karthiproffesional@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <1e2b77c7916259e3e269d19f637c29427c175350.camel@codeconstruct.com.au> References: <1e2b77c7916259e3e269d19f637c29427c175350.camel@codeconstruct.com.au> 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" put_fifo_with_discard() acts as both producer and consumer on the kfifo: it calls kfifo_skip() (advances out) and kfifo_put() (advances in) from the IRQ handler without synchronizing with snoop_file_read(), which also consumes via kfifo_to_user(). On SMP systems this concurrent access can leave (in - out) larger than the ring buffer, so __kfifo_to_user()'s clamp to (in - out) is ineffective and kfifo_copy_to_user() can attempt a copy_to_user() past the kmalloc-2k backing store: usercopy: Kernel memory exposure attempt detected from SLUB object 'kmalloc-2k' (offset 0, size 2049)! kernel BUG at mm/usercopy.c! Call trace: usercopy_abort __check_heap_object __check_object_size kfifo_copy_to_user __kfifo_to_user snoop_file_read vfs_read Serialize kfifo access with a per-channel spinlock. copy_to_user() runs after dropping the lock, since it may sleep on a page fault. Fixes: 3772e5da4454 ("drivers/misc: Aspeed LPC snoop output using misc char= dev") Cc: stable@vger.kernel.org Signed-off-by: Karthikeyan KS --- Andrew, Thanks for the review. > This seems inappropriate and I expect is flagged if you compile with > CONFIG_PROVE_LOCKING=3Dy or CONFIG_DEBUG_ATOMIC_SLEEP=3Dy v4 drains the kfifo into a kernel buffer via kfifo_out() under the lock, then performs copy_to_user() after dropping it. (cf. drivers/gpio/gpiolib-cdev.c, which drains under its event lock and copies outside it.) > ensure you develop, build and test on recent releases Tested on both v7.1-rc5 and v7.1-rc6 with PROVE_LOCKING, DEBUG_ATOMIC_SLEEP and HARDENED_USERCOPY enabled: read path round-trips correctly, no lockdep splats, no atomic-sleep warnings, no usercopy aborts. Changes since v3: - Replaced kfifo_to_user() with kfifo_out() + copy_to_user() to avoid sleeping under spinlock - Rebased onto v7.1-rc6 drivers/soc/aspeed/aspeed-lpc-snoop.c | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/drivers/soc/aspeed/aspeed-lpc-snoop.c b/drivers/soc/aspeed/asp= eed-lpc-snoop.c index b03310c0830d..0fe463020e25 100644 --- a/drivers/soc/aspeed/aspeed-lpc-snoop.c +++ b/drivers/soc/aspeed/aspeed-lpc-snoop.c @@ -74,6 +74,7 @@ struct aspeed_lpc_snoop_channel_cfg { struct aspeed_lpc_snoop_channel { const struct aspeed_lpc_snoop_channel_cfg *cfg; bool enabled; + spinlock_t lock; struct kfifo fifo; wait_queue_head_t wq; struct miscdevice miscdev; @@ -115,6 +116,7 @@ static ssize_t snoop_file_read(struct file *file, char = __user *buffer, { struct aspeed_lpc_snoop_channel *chan =3D snoop_file_to_chan(file); unsigned int copied; + u8 *buf; int ret =3D 0; =20 if (kfifo_is_empty(&chan->fifo)) { @@ -125,11 +127,22 @@ static ssize_t snoop_file_read(struct file *file, cha= r __user *buffer, if (ret =3D=3D -ERESTARTSYS) return -EINTR; } - ret =3D kfifo_to_user(&chan->fifo, buffer, count, &copied); - if (ret) - return ret; =20 - return copied; + buf =3D kmalloc(SNOOP_FIFO_SIZE, GFP_KERNEL); + if (!buf) + return -ENOMEM; + + spin_lock_irq(&chan->lock); + copied =3D kfifo_out(&chan->fifo, buf, + min_t(size_t, count, SNOOP_FIFO_SIZE)); + spin_unlock_irq(&chan->lock); + + ret =3D copied; + if (copied && copy_to_user(buffer, buf, copied)) + ret =3D -EFAULT; + + kfree(buf); + return ret; } =20 static __poll_t snoop_file_poll(struct file *file, @@ -153,9 +166,11 @@ static void put_fifo_with_discard(struct aspeed_lpc_sn= oop_channel *chan, u8 val) { if (!kfifo_initialized(&chan->fifo)) return; + spin_lock(&chan->lock); if (kfifo_is_full(&chan->fifo)) kfifo_skip(&chan->fifo); kfifo_put(&chan->fifo, val); + spin_unlock(&chan->lock); wake_up_interruptible(&chan->wq); } =20 @@ -228,6 +243,7 @@ static int aspeed_lpc_enable_snoop(struct device *dev, return -EBUSY; =20 init_waitqueue_head(&channel->wq); + spin_lock_init(&channel->lock); =20 channel->cfg =3D cfg; channel->miscdev.minor =3D MISC_DYNAMIC_MINOR; --=20 2.43.0