From nobody Mon Jun 8 05:24:53 2026 Received: from mail-qv1-f45.google.com (mail-qv1-f45.google.com [209.85.219.45]) (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 2B1113644DB for ; Fri, 5 Jun 2026 15:52:24 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.219.45 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780674748; cv=none; b=BzsB75VDzPiJee+zhPMz5EtB9e2TJNlHrcqFf4tA0gacglvfKsOsdloPGMDtHm7gVaesSyMOJGrGZCFLPBQ2z44HnoSB1yB14oW4Nqb4M1lA3kNUHAOpD9DUPjI1fUurUstRTtZemSKvZJkYz2Lt/pnxvntMch0iKqjysAOAyYk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780674748; c=relaxed/simple; bh=Ot/L+UG3DtC+N56kxMcCI4qGI03iutg/rdVqqNsKCg0=; h=From:To:Cc:Subject:Date:Message-ID:MIME-Version; b=ZT8MQwv1wKnU6FYuN9KaPGpeYkgq7DbfjYIQTde8RBbWt0Md3uHAhzckpERzqiOSKDmcNFtOZeAXtoJAE34z6jjf4yNgxLrcbsQ8hLXx6vRwBJxFicyctp04LvYpQf7slwsu7YFxe0iswDSrJXxW62kOLY9j97i9+Lk/hcYgwiE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=trailofbits.com; spf=pass smtp.mailfrom=trailofbits.com; dkim=pass (2048-bit key) header.d=trailofbits.com header.i=@trailofbits.com header.b=GkJTZfYZ; arc=none smtp.client-ip=209.85.219.45 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=trailofbits.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=trailofbits.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=trailofbits.com header.i=@trailofbits.com header.b="GkJTZfYZ" Received: by mail-qv1-f45.google.com with SMTP id 6a1803df08f44-8ccedaf0b54so12787686d6.0 for ; Fri, 05 Jun 2026 08:52:24 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=trailofbits.com; s=google; t=1780674744; x=1781279544; 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=BY5yDN7sJ2DYlATOXPONuiiT9XcmBu5m8XI1ujhkFaM=; b=GkJTZfYZrXqPLWlN9/sY7eP+ENPvBKb/fjDXvW3v8aQfAZ5lTDjf4aGpR8D8zb97TY sd8zuV8J0hl3idKS6n6ZMoXk/mQqiKVCCijJF5QsYJBD26/16++dzTau9wwAYU+xvkve YuW7Xv/99GCFpV+fHCB+vfB/7d6T+d/ubbnuih8HMS4wDaUZahztgL70TGv3lI0FygZq 0b43jpXiEet9gXukyGUK83i3075vVlcB7GejRYyPwO12x0RABzb58IDKgWeJVvhglK7o qZF4Xd2SdWbB0KYbe+bP6NfUbQFaxKaHV8g/IvomvJVmBsr0RaPzjNOvec/irOINNSXI EpLQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1780674744; x=1781279544; 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=BY5yDN7sJ2DYlATOXPONuiiT9XcmBu5m8XI1ujhkFaM=; b=JCVvbpzyXmFdu8Nmp9vZ6PLRG7k88mu0k9Foz+uDmHt8HiwURD6tPfXKLKnYE91TL7 Cx0tKyro/dfJYjBHAjgDct9yipbG/YZFPQGHzw9pDnJZRNhx2kuVEQjwcHEmRccwCy9C D+Z9JshKhqmlNBcKyuo81SGGG3J9UXMq6qmfWIlEJI/R1TEQrdz7fe58e5MD1ZW5yVD5 abVYBHHUE8QROVw5W1F3KTqJtX/Gl3lSx1du3ZyBqysMkbgVruZ1UezlmvnOonTNRXjc P5xB0XY1FNy/w4wCsjKXTUmadsUDmf3eKel+9eVeW9tWWZUWmvHgScXJF162k5ZFW7At F2PQ== X-Forwarded-Encrypted: i=1; AFNElJ9YPWNuaePqub4lONSAMIpWEuhIAnIDqOJeCciF8YxRNIYziHXs2dKMyc+4pGh5RtwdW1n9Eer0JUj4rbk=@vger.kernel.org X-Gm-Message-State: AOJu0Ywdc1FJq2ND7LcLGlopXsy+MVMusWm+Zd1GzgCL3OC5nVfyQKsq 69wlzxSaOpFXmzn0wUL9uEzzZ0r9cFayJJkToDaKkcG8V8XaVlREMxg1GpoF/mthGfBVR7HUeuH oxivV+5s= X-Gm-Gg: Acq92OGn1wVlv8RSRVx1/UU0sCuOfNyzKNi48VwcutofKLbqRhuqhdGoVSr/7rHA6xj umimx8HQV5site2ggENUyAnYUnJNV57oJ5H7xS8tYMNYFbEUzPKPpzoi2q7rmmUG+mQJqjHfyBv x6MkHRXWLzhetijtf3KoTPKV5HiuijFkBhvgLzz6Rwmb/N5MUz/wNA+CcM6sPyCPf9qXdxwmvLR Zd1JBe2Kei3a3jK8V0SQv39lpTQHt1TRCmjgFhFN6ydjSiqcRD/63Iopc+GJD0513zqdj+yvc0g xRZXyW+xgb8guN0+tlokmmTux3tIpzSYOzDOHizRHaj/5HwNC1z4WJPSVas++BH2SDsNhnS4v20 TwcxtS3KyIU3ePkO6/cC+K8sHIdzGZrbeMiNfNbTX6F8Wr4VJr+6ShTyon/GAPiq7yUPbq5gaey 7yHQDbqK+r3FRxOrj7yGgvSGWRw1SZpgXE0dNk7w== X-Received: by 2002:ad4:5a4e:0:b0:8a0:4e92:c45f with SMTP id 6a1803df08f44-8cee5fb63b5mr50791386d6.11.1780674743846; Fri, 05 Jun 2026 08:52:23 -0700 (PDT) Received: from localhost ([161.35.96.86]) by smtp.gmail.com with UTF8SMTPSA id 6a1803df08f44-8ceccd9fd77sm85763446d6.10.2026.06.05.08.52.22 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Fri, 05 Jun 2026 08:52:22 -0700 (PDT) From: Samuel Moelius To: OGAWA Hirofumi Cc: Samuel Moelius , linux-kernel@vger.kernel.org (open list) Subject: [PATCH] fat: reject BPB volumes whose data area starts beyond total sectors Date: Fri, 5 Jun 2026 15:52:15 +0000 Message-ID: <20260605155216.2126545-1-sam.moelius@trailofbits.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: quoted-printable Content-Type: text/plain; charset="utf-8" fat_fill_super() subtracts sbi->data_start from the BPB total sector count before computing the number of clusters. A malformed image can declare a total sector count smaller than data_start, causing the subtraction to underflow and the mount code to derive a plausible cluster count from the FAT length instead. Reject such images before the subtraction. In QEMU, a crafted FAT image with total_sectors=3D2 and data_start=3D3 mounted successfully before the fix and reading a file returned bytes stored past the BPB-declared end of the volume. With this change, the same image is rejected during mount. Assisted-by: Codex:gpt-5.5-cyber-preview Signed-off-by: Samuel Moelius --- fs/fat/inode.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/fs/fat/inode.c b/fs/fat/inode.c index 28f78df086ef..168a278cc60c 100644 --- a/fs/fat/inode.c +++ b/fs/fat/inode.c @@ -1738,6 +1738,14 @@ int fat_fill_super(struct super_block *sb, struct fs= _context *fc, if (total_sectors =3D=3D 0) total_sectors =3D bpb.fat_total_sect; =20 + if (total_sectors < sbi->data_start) { + if (!silent) + fat_msg(sb, KERN_ERR, + "data area starts beyond volume (%lu > %u)", + sbi->data_start, total_sectors); + goto out_invalid; + } + total_clusters =3D (total_sectors - sbi->data_start) / sbi->sec_per_clus; =20 if (!is_fat32(sbi)) --=20 2.43.0