From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-pl1-f170.google.com (mail-pl1-f170.google.com [209.85.214.170]) (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 4DBE0361DD0 for ; Tue, 5 May 2026 17:56:00 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.170 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778003761; cv=none; b=RXq4PAy3tE2xaQmh0Xa4RSn/gggP5fXEBh94P6ukUC3OJ8cj1VgpaF1zj8H2kgXyxROaT/Qj2cLCYAq//91LJIWdLIZX9yXmVrJk96ALqt9sPbftdQsMoQsDtby2oSXZ3kdhzBMnCNvnfTOhiFQkSXLDHjuhEvAQXvzVlFrvGhg= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778003761; c=relaxed/simple; bh=NxW9I3BhNiO+2+AGW6hS9Oeq4rZDxWVX3/T3h0T7XBo=; h=From:To:Cc:Subject:Date:Message-ID:MIME-Version; b=J2v2KJt5D61uBv8+eHmWjRfM6qCAaFohXY/5ETESmm7/XZqlky4/XgrmYHNdVGeQXcPJ4Cpx7SS28Le+xPUKojSrpS7h4CqgEVc8I/nN9U+NHon1MdoQxCtULmQnLQdk0YeFlUc+lxgb0vxiUWIvZs31pnrp/7frXcRVlf68Acs= 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=PO2CdVYH; arc=none smtp.client-ip=209.85.214.170 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="PO2CdVYH" Received: by mail-pl1-f170.google.com with SMTP id d9443c01a7336-2a7a9b8ed69so48452835ad.2 for ; Tue, 05 May 2026 10:56:00 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1778003760; x=1778608560; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to; bh=Tx4i6Txgy6DoPF46xtQdVqhEuZCvacl8wPfj2s4kHQ8=; b=PO2CdVYH2nIRGDWkMlw6mQ3NSfdsbJZ/Ly075xIzugYzJIhaEkzbYGFsqsdzn8ztJb a269uFz3AUEDUP2HZ41rMJN/rqxDUk+pe5GZwbptPdGil8eHDn/sZEtlhAUkiUyS5NvS coL3yvFMGrsZnltuEx6UucsgNjnRt4AOwUtcuFHAUT17OQj3l0WSkfqIp58QcO82TRTu 0qKmjrmZWikPdsMeX1dK9a2Nra6JvRxjcc8m7Z3NW/PKiKU/RI4MRNS700AyxwBGWO8k fna2lcjjC8aaLHZwJxUKaNuyX+rui2aIdAuBpJsIgV3961tWLkiXk1t1pTJGHZ6cTFMn GMNg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1778003760; x=1778608560; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-gg:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=Tx4i6Txgy6DoPF46xtQdVqhEuZCvacl8wPfj2s4kHQ8=; b=MAN0TVh1EwfHLyZtk2T+YMNZCeAj6lk/OE/vfkKTt3O42kPzfG6rEPy5Acow7Z/wTU oIyyrfMUzW552lup7T5l5yAOOsyIw0dQKfXRlBzV5sAd6d/Z4KfcGGIrdOmCPUARhAK0 YpXg95zesFPZ14RAcmVoAl8e2gkT4Wa2FFH9axEkkRdG7Dg9wvrvLDm4bpyWbbUfjpJq i0Ne7VXiLErWf2rJ1isAMlzFKcbXzlLMbTmg3eyQ3JpwcKENhmTEjRbCL+Nk3vGk817o t4Y+c9D3CnvCBGt3Er8ZjBJOD7Zk4TdQgdwa2ntgL20vlxgu0CO23S3VBfYYAKbrBHKo js+w== X-Forwarded-Encrypted: i=1; AFNElJ92tXC6uFLk5v2UP6yJIcVeDo6bWb8FXJ8dtHBUYkrPUleNap9yKX9CBMem8EfEEHY9dYMGSFMak2WMNaY=@vger.kernel.org X-Gm-Message-State: AOJu0Yw7/QvdC8E5mL2EnQqOOGUyNJugZ7QoIRfnjby/cEYStPg4oVrK pE55c1D0yrIXUeT77AXrDliYAasCUkSyFhDLByInJqFysPXslrfNw02u X-Gm-Gg: AeBDievIBkbjUMNIXL2UzV7mZ8EwhPRZSZ+rPl/DjIDmMGjSiqM6YljstE5HyaMPzVx YFpOhylceZdroqmo33hPvVYOQz9yK5x5WXPEU86Yq32FwBcoxWL2SNi/GbIvTHRRrvvKVu/Wc7D Z1XeGF/Mw/Uaj3M5FZdyYH6kS8fOeT0X08F9sebtnKOX0ClxUVUq1Iwlmant0RfY1zwPhQT634X cAXmtojRB1LRhy+YbHDYowP/sPxTicFYuVmddTANVcRLHoCQNNPPGbRHEubKMVDYlzAyfV2LvLu F0Xp68WTeOX8+WKeP61xefQKsAQzdAvmmemvAZT7zZR5gV7amyc1CVGSGLHYngM06Qh7jCi/ahD Kh0FTmFaEjQv0ytFT/KZfBoKc7fHXoKFdSh1330PUvKXCh8/ywOLDFOubv8De3xz0QWcJBOoI1N 87DhDqDnKmoMxPc55mZnin/sqCmhhYBLiakre9eReEWxWp/yzrdIYXtlNsH+MrzIZI6qrjWBVEK qL5IVfvbZDa4FCoFQ9l3kw= X-Received: by 2002:a05:6a20:1592:b0:3a2:f2b1:1ac with SMTP id adf61e73a8af0-3a7f1fb6640mr16655349637.44.1778003759641; Tue, 05 May 2026 10:55:59 -0700 (PDT) Received: from SLSGDTSWING002.tail0ac356.ts.net ([129.126.109.177]) by smtp.gmail.com with ESMTPSA id 41be03b00d2f7-c7ffbba635dsm13531169a12.3.2026.05.05.10.55.57 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 05 May 2026 10:55:58 -0700 (PDT) From: Weiming Shi To: Wolfram Sang Cc: linux-i2c@vger.kernel.org, linux-kernel@vger.kernel.org, Xiang Mei , Weiming Shi Subject: [PATCH v3] i2c: smbus: reject oversized block transfers in the common path Date: Wed, 6 May 2026 01:55:11 +0800 Message-ID: <20260505175510.1403736-2-bestswngs@gmail.com> X-Mailer: git-send-email 2.43.0 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit The SMBus block transfer length data->block[0] is validated in i2c_smbus_xfer_emulated() but that check runs too late for tracepoints and is skipped entirely when the adapter provides a native smbus_xfer implementation. This allows user-controlled oversized block lengths to reach tracepoint memcpy calls and driver callbacks unchecked. Add an early validation in __i2c_smbus_xfer() that rejects block transfers whose caller-supplied length is zero or exceeds I2C_SMBUS_BLOCK_MAX before any tracepoint fires or driver callback runs. data->block[0] is filled in by the device on SMBus block reads, so the check is scoped to operations where the length is actually supplied by the caller. This is consistent with the existing -EINVAL convention in the emulated path and protects all downstream consumers at once: the smbus_write tracepoint, all native smbus_xfer driver implementations, and the emulated path. Two distinct bugs are fixed by this change: Bug 1: smbus_write tracepoint OOB (include/trace/events/smbus.h) trace_smbus_write() fires before any validation and copies data->block[0]+1 bytes into a 34-byte event buffer. With block[0]=0xfe the tracepoint copies 255 bytes, overflowing by 221. BUG: KASAN: stack-out-of-bounds in trace_event_raw_event_smbus_write+0x27c/0x530 Read of size 255 at addr ffff88800d98fcf8 by task poc_smbus/91 Call Trace: __asan_memcpy+0x23/0x80 trace_event_raw_event_smbus_write+0x27c/0x530 __i2c_smbus_xfer+0x43a/0xa40 i2c_smbus_xfer+0x19e/0x340 i2cdev_ioctl_smbus+0x38f/0x7f0 i2cdev_ioctl+0x35e/0x680 __x64_sys_ioctl+0x147/0x1e0 do_syscall_64+0xcf/0x15a0 entry_SYSCALL_64_after_hwframe+0x76/0x7e Bug 2: i2c-stub I2C_SMBUS_I2C_BLOCK_DATA OOB (drivers/i2c/i2c-stub.c) stub_xfer() implements .smbus_xfer directly and only clamps block[0] against 256-command, not I2C_SMBUS_BLOCK_MAX. With block[0]=0xff and command=0 the loop accesses block[1+i] for i up to 254, far past the 34-byte union. UBSAN: array-index-out-of-bounds in drivers/i2c/i2c-stub.c:223:44 index 34 is out of range for type '__u8 [34]' Call Trace: __ubsan_handle_out_of_bounds+0xd7/0x120 stub_xfer+0x1971/0x198f [i2c_stub] __i2c_smbus_xfer+0x306/0xa40 i2c_smbus_xfer+0x19e/0x340 i2cdev_ioctl_smbus+0x38f/0x7f0 i2cdev_ioctl+0x35e/0x680 __x64_sys_ioctl+0x147/0x1e0 do_syscall_64+0xcf/0x15a0 entry_SYSCALL_64_after_hwframe+0x76/0x7e Both traces reproduced on v7.0-rc6+i2c/for-current with KASAN+UBSAN. Fixes: 8a325997d95d ("i2c: Add message transfer tracepoints for SMBUS [ver #2]") Fixes: 4710317891e4 ("i2c-stub: Implement I2C block support") Reported-by: Xiang Mei Signed-off-by: Weiming Shi --- v3: - Also reject data->block[0] == 0 (Wolfram Sang); scoped so that SMBus BLOCK_DATA reads still work, since block[0] there is filled in by the device, not the caller. v2: - Moved the check from stub_xfer() into __i2c_smbus_xfer() so it covers all callers, not just i2c-stub. This also fixes a separate OOB in the smbus_write tracepoint that hits the same missing validation from a different angle. drivers/i2c/i2c-core-smbus.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/drivers/i2c/i2c-core-smbus.c b/drivers/i2c/i2c-core-smbus.c index 71eb1ef56f0c3..ad6acb5ebadc3 100644 --- a/drivers/i2c/i2c-core-smbus.c +++ b/drivers/i2c/i2c-core-smbus.c @@ -566,6 +566,18 @@ s32 __i2c_smbus_xfer(struct i2c_adapter *adapter, u16 addr, if (res) return res; + /* Reject invalid caller-supplied block lengths before any + * tracepoint or native smbus_xfer callback runs. + */ + if (data && + (protocol == I2C_SMBUS_I2C_BLOCK_DATA || + protocol == I2C_SMBUS_BLOCK_PROC_CALL || + (protocol == I2C_SMBUS_BLOCK_DATA && + read_write == I2C_SMBUS_WRITE)) && + (data->block[0] == 0 || + data->block[0] > I2C_SMBUS_BLOCK_MAX)) + return -EINVAL; + /* If enabled, the following two tracepoints are conditional on * read_write and protocol. */ -- 2.43.0