From nobody Thu Sep 24 15:10:58 2026 Received: from mail-pz2-f43.google.com (mail-pz2-f43.google.com [74.125.228.43]) (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 F2C845505CB for ; Tue, 22 Sep 2026 14:01:43 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.228.43 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790085705; cv=none; b=MKRiVfF4VzEibBEIA1xSkgQV3liiCupwh2MyD2ynzo970L4aB+Xqtb2ugGi2XtFKMAf6NxXOIYPktCtLehJ5Xh+P9xYSZAEREiFVjAOWEP7nE1M8LbVBXs6LxtgePQUIxCneHRRCObLbUlbFF8YMU5ngP/qsmfQ5skmi7Be5r6w= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790085705; c=relaxed/simple; bh=Z0x5CU2E73GGQT0WGdYVgrKEzFDVlQaVuFg3+JZSUvw=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=fqG3KgcE0PeXq06G3R02O8ZMDpsKjMqGqGY7BSREkzHpNlrFSPOTLmXJQTSKbbaQbV29Fyjyve+hJXP0h28nw9MgyWx6iXZslKLAvsDwKBVidVvylMVUdNsMerl4z1XxA8btyZojr084tIsqezt0Z06+QEFyvVadiXmHeDbShHE= 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=cm3jTXUW; arc=none smtp.client-ip=74.125.228.43 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="cm3jTXUW" Received: by mail-pz2-f43.google.com with SMTP id d2e1a72fcca58-8631d0023daso3150963b3a.2 for ; Tue, 22 Sep 2026 07:01:43 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1790085703; x=1790690503; 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:content-type; bh=5oGWhynSEKne6RN1QxHEC9k9P8vjg9REo1kgWqBAqDc=; b=cm3jTXUWDShvamxv6PLkK2K6Q9MB4rEk+cAcGymFs4WwuepqrzAEbb2masvMl121wA W/BnezkUy1olSuw4M+vV01S3/xO/HelaHrcRLHpq6zb3DN+ADEqFqjAPLv38QO5ExjR9 oc58I81SoQAcEvorEif0qF+a9cKLFX2j/h/cl//a8iOz1NvcudBwXhiKkb1SXg9aaC9O 8gCcro5Ydt9CnNUER5DPsolm3YfLlOWnhGsEQ6DZnOCBmZr9WYgcdb0myalLQdyfHho9 4UHunuTCcrLRllkBpn90adOLN5VHVGy2siZGyAo79DRCBvr8+Gv+gH0gCMEhl+aclIdw pqIw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1790085703; x=1790690503; 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:content-type; bh=5oGWhynSEKne6RN1QxHEC9k9P8vjg9REo1kgWqBAqDc=; b=inPoYB6pwIFLsaYKoj8MkIiKtUwnkUcvk0Pw+2DLxelOeNu/CxTNiFLkSinM3ldeQT b8c3AJCGTQGkefuzG7pSSXLhN/gPsDdXPw1JNQJR1dih6Tz7DrUn7vMazuoxm6tm+wEd kTyRB1xTFHet8g0vL8Yga9CeLzyYRWYS+l7i53HXAw6rlTSW3p2Svkh6s7LU0KUD1Xrb xhbU+mSUytH+ZxVz2bRdfo5jmO/ITZHe+U41IV3xYB9QsiL/DLzr8xHIGzuJgfe/GZLr XlJefwEPc2zPTiYCIHHssQYvagsncEaPk27ZFyQM1gQMHYxmFw82/sNXPz9nm4Mmn+kO 1mzw== X-Forwarded-Encrypted: i=1; AKwUvBzw7H3DkvlyhLIkAcEss4QKtD2DjMXFOzFwxdGoZqqbdiDfySyJSmFh808H4dG93mMNVf5opkMC5Ytc6g0=@vger.kernel.org X-Gm-Message-State: AFuF++n459W388XMnioPZfgDRJGi9qjEHqsBy8qPs8q7kYGb1snyfGFN w7oFlvOuPNy0+Z4mKhX/jTevOTruo+MjAq5AKGgDZsGXFsVLNtXAsGdJ X-Gm-Gg: AYBFou1JsdFpdznsITcdoUghgxtBmz1BnK2+3ZzIXmm1hvsLgsgtoY0yMZT5UNc+dzc AxROxa+CIb89YzPkNNb5BP+/gaQtU7Qv3chM2JT3/C+6C1Mrmk0610TvBBG2KR27b40hBP1zxFD fCNJ4LvNMcsnSCR/KNdBw/+Lxbglh98rg9rFAoIgI6hHh7cTcRTEdEjvhIeMaOHjW5bZ0//dIUx ljolMfo6u8bthXe6DmQkiVokYNceJgf4Bx1Dy4V4wlkcWDZktU+0I1ItIwq7p4QUgJ8ZZHTER7L SYZ3AH/EX0JuV5lN5go4hdQ+2R9MzuqKYLw8qHusbiwRVI93tTKbLtBxJ0OxiZpno/Qz/NKYgmE NNbCqBnJbr3ZAnC/lQ3rcHSFrGfCBBUUwkquhTqb4+2GMjnptEjCl3l9MK5KvBLNQpLbDEQJFWf fErNMsa9saPiDnPfDTcZnnsaHnv96m6VzdneaFDGkQKfopae3nu/sc5XS9uwZC8KDTAK7JcmgQH upjfrJNw6kNDE02/ZMOCh3VhZiJSvXi13jBSDvw1oyc0ZczJQ2nSvib76fC4R/3WKePD0KzLQqP Bi7BRANKAT/+sYcWYaZs/QNDHeEbqH5g09EglvQ33SK2K5PTgg+wQZjdd/jWbRelQ/V6nTUTrw= = X-Received: by 2002:a05:6a00:1f1a:b0:878:37b2:df98 with SMTP id d2e1a72fcca58-87c8500a986mr1360521b3a.56.1790085702880; Tue, 22 Sep 2026 07:01:42 -0700 (PDT) Received: from spider.bream-herring.ts.net ([103.252.203.158]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-87c329c813fsm932803b3a.38.2026.09.22.07.01.41 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 22 Sep 2026 07:01:42 -0700 (PDT) From: Matthias Goergens To: Jan Kara Cc: Christian Brauner , Yichong Chen , linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH 1/2] isofs: validate directory records in isofs_read_level3_size() Date: Tue, 22 Sep 2026 22:01:36 +0800 Message-ID: <20260922140137.1768064-2-matthias.goergens@gmail.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260922140137.1768064-1-matthias.goergens@gmail.com> References: <20260922140137.1768064-1-matthias.goergens@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" isofs_read_level3_size() walks the multi-extent directory records of a file and dereferences de->size and de->flags for each one without ever checking the record's length byte. A record with a short length placed near the end of a block makes those fixed-field reads run past the record, and for a record at the end of the last block of a page, past the buffer. readdir, lookup and the NFS get_parent path have validated every record with isofs_dir_record_valid() since commit e2ee4078ec58 ("isofs: validate directory records consistently"). Use the same helper here. It rejects records shorter than the fixed part, records whose name would not fit, and records that would run past the block, so the straddling-record copy below can no longer be reached with a bad length. Found by fuzzing fs/isofs in a userspace harness with ASan (heap-buffer-overflow reads in isonum_733(de->size)). Signed-off-by: Matthias Goergens Tested-by: Matthias Goergens --- fs/isofs/inode.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/fs/isofs/inode.c b/fs/isofs/inode.c index 337836a0a170..c9bc1f479161 100644 --- a/fs/isofs/inode.c +++ b/fs/isofs/inode.c @@ -1208,6 +1208,14 @@ static int isofs_read_level3_size(struct inode *inod= e) continue; } =20 + if (!isofs_dir_record_valid(de, offset, bufsize)) { + printk(KERN_NOTICE "iso9660: Corrupted directory entry in block %lu of = inode %llu\n", + block, inode->i_ino); + brelse(bh); + kfree(tmpde); + return -EIO; + } + block_saved =3D block; offset_saved =3D offset; offset +=3D de_len; --=20 2.55.0 From nobody Thu Sep 24 15:10:58 2026 Received: from mail-pz2-f43.google.com (mail-pz2-f43.google.com [74.125.228.43]) (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 319C0550DC0 for ; Tue, 22 Sep 2026 14:01:45 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.228.43 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790085707; cv=none; b=YA/BsDMn7B1DFmEtMpBibYQPASEvz0SFfnjL9BOaOa8u7Srd81KaRGeFfuNq3CLsmfu3CLWGXEX8Ld7vrY9B8QvKV8WeiyoVfMc3yQkc1JhbJPB3U0vVwy8eucvFEuDLppsM9bi5hqJEenhMkYl5h4t6PEbu0cVwq0IqoVhtHqo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790085707; c=relaxed/simple; bh=3U4Ql79vVPopRfavLTmA8NqbKhWApnQJ1mkN1HYYhho=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Tc228kYX1kuQQHJsauRm/Z+/IDHRrh0B51vCfa5l18BmWW0xM2Joe8xeMJoYQZLZAW3SjQ504MxSfl+m2jyb2C6OqhpyfMDMrwHC7jA3PN/RY0CGsyrX4m6dzat1B4hC3v5Q7eAnTsjDwGIgbnRzQRHpHmGymsQNup7j4drdHBE= 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=AmMr1pwB; arc=none smtp.client-ip=74.125.228.43 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="AmMr1pwB" Received: by mail-pz2-f43.google.com with SMTP id d2e1a72fcca58-85a4329731cso3312001b3a.3 for ; Tue, 22 Sep 2026 07:01:45 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1790085705; x=1790690505; 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:content-type; bh=YoKssft9l1zcAv984LexCRNeW4PIN0qjiBZ2Kra0Bhw=; b=AmMr1pwBMOxJAa7hf4+COcophPdnVo/YwXW0KkVgSTjTL45LA20p20uxaR13K6L1lw LHIWD5tmt+nN9I0Qhvq8NLuO938+cJEotOErXbv4GPEdI4Vokdjt/KLY5q0aRwLL9S/Y 5mb3tp8kxaqZABOYftrxp5uRu5KNyDOTbnIbiJ+XqP0NQOLqtZetc8aQDgf4cGjAnnhd x45xlm+1vHpSAE8ZnENMWP9gMNCmfiMC7T0PO3hCEZD9qdrDkbDsqjy4ZXVj60GQhjxn S2WddrfJBGJLnP9OIBbocs2ifhf1TYp3UD0XjudeSJ/FQSY/oCF6E/vlzKzmO3KobVNS E6xw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1790085705; x=1790690505; 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:content-type; bh=YoKssft9l1zcAv984LexCRNeW4PIN0qjiBZ2Kra0Bhw=; b=k/tGQ5GZQs6+BSC2Xlof2bySYJDSfOPb+5e43YYfdJIpaiYcy34dvpYs9wJOHIUac2 SkVeC0USCwLN9quidznFnGWWXmZwNdf007TiCVkXPJ1JQFd1abDMzXp1hbQFgHyqHaAi CvvWty3rjhAdKId4yEb4BpNXlvTLB49Ejqzz1Lzf3cbl5r3G/iKrpAk5w0niUufgGsJ4 WmgNnhKcB7GahwKs5VHGE23X3UF6v76KUWaAQd5ukk74n8TW6qUPm4Y/VMt6wYKo67SA WkS4x5WwhIGFycOTGlZPZ1MACouj6qec8YwQlVNmIflqzh/ELdjSOqwz6TPlxsbzzm/s Lj8g== X-Forwarded-Encrypted: i=1; AKwUvBzO6ahvlVq+oP9s49B5HN12DJTMM1Lsx7YpmLdDUqrxLwrmhk0nmFgF3Ea2P6WNR2PToxBtf+NPqA+ZSkc=@vger.kernel.org X-Gm-Message-State: AFuF++kj/cutN3OjKU3G4CdaZg5GLcNYLuYHQHt8NtmfXv5dl6JolYXO 9yaMd3IIFAsFQQ8y7riMOZtl/q9C9owXdtGY/hiOHArlUMUy3MWb5DBl X-Gm-Gg: AYBFou0PHGQeTH9XibUxK7j8SQog5mlHUFFgXO7UkpeOmeRP6Bn2WFMwus0bRFgg8eJ 7+jKeJvI1JNTxIuD/tqiiccu7fAKa1dFBWfFEirpgKgfpRwK6fTewcmn25bCa3jmt1tEP0Odxaj vYW3z2e7ThP74hEydRtC1BVoK3o7AaOI2U+EXOmYMMoY5+KyOw2govxAqaxcyGregW28enqJLK5 qMHLPWkt9ZJ9w4g7c6S1XWizqTfiPR/j/jA9XeEF3SuZ87PNQ635q1WtlmtFogJ+fXuaexUPBG9 lfg89yvmwrQ5xA84rhd6IkUJZuumtHtIW7WZgXhd5+O4Gd7Iv1U9Ix049YfSdS0JYNk57z/TaxQ ajnf4u/qCwOtZvBMWLXeZbKc5evaEBtYODp37Hdn4dFKFpROZxp3fp7PXX64tUuT1aF3apu4yqA mjP+gqmU/9t51qbrch33rbVucCiBd7cqlVWOnRk1OjNS9yZn4l0LU322rS+7VOnrwSNKNU4sdI/ 10Q51nvQYm1/WogSIITZHNiy1deVw/Usfivp9Fdyl9xv7TaL3XD4A2NtazSVNs+AouPIaABGM0R UzB+gd+Wia3gEXPJWi19Pf4P1I5R3UAYmqdw3QKrKvfpjBJmxgfN8llhZUTnJOA= X-Received: by 2002:a05:6a00:8085:b0:874:708d:b620 with SMTP id d2e1a72fcca58-87c8403d93amr1298947b3a.30.1790085705347; Tue, 22 Sep 2026 07:01:45 -0700 (PDT) Received: from spider.bream-herring.ts.net ([103.252.203.158]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-87c329c813fsm932803b3a.38.2026.09.22.07.01.43 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 22 Sep 2026 07:01:44 -0700 (PDT) From: Matthias Goergens To: Jan Kara Cc: Christian Brauner , Yichong Chen , linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH 2/2] isofs: drop support for level 3 records straddling blocks Date: Tue, 22 Sep 2026 22:01:37 +0800 Message-ID: <20260922140137.1768064-3-matthias.goergens@gmail.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260922140137.1768064-1-matthias.goergens@gmail.com> References: <20260922140137.1768064-1-matthias.goergens@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" isofs_read_level3_size() is the third copy of the directory record walk and the last one that still reassembles a record spanning two blocks. Now that it validates every record with isofs_dir_record_valid(), such a record is rejected before the copy can run. ECMA-119 does not allow directory records to straddle sector boundaries, the same assumption commit b2eb2e288604 ("isofs: Drop support of directory entries straddling blocks") relied on when it removed the equivalent code from readdir and lookup. Remove it here too, along with the temporary record buffer it needed, and fold the end-of-block case into the existing zero-length check the way commit bda8d8d49ca1 ("isofs: Fix handling of directories with tight blocks") did for the other two walkers. That check has to cover both cases. The code being removed here ran on "offset >=3D bufsize", so it was also doing the block advance for a record that ends exactly at the end of a block, and dropping it without replacing that is what went wrong last time. Signed-off-by: Matthias Goergens Tested-by: Matthias Goergens --- fs/isofs/inode.c | 38 ++++++-------------------------------- 1 file changed, 6 insertions(+), 32 deletions(-) diff --git a/fs/isofs/inode.c b/fs/isofs/inode.c index c9bc1f479161..70097456b721 100644 --- a/fs/isofs/inode.c +++ b/fs/isofs/inode.c @@ -1174,7 +1174,6 @@ static int isofs_read_level3_size(struct inode *inode) unsigned long block, offset, block_saved, offset_saved; int i =3D 0; int more_entries =3D 0; - struct iso_directory_record *tmpde =3D NULL; struct iso_inode_info *ei =3D ISOFS_I(inode); =20 inode->i_size =3D 0; @@ -1198,9 +1197,12 @@ static int isofs_read_level3_size(struct inode *inod= e) goto out_noread; } de =3D (struct iso_directory_record *) (bh->b_data + offset); - de_len =3D *(unsigned char *) de; =20 - if (de_len =3D=3D 0) { + /* + * If we are at the end of a block (or at its zero-padded + * tail), move on to the next block. + */ + if (offset >=3D bufsize || de->length[0] =3D=3D 0) { brelse(bh); bh =3D NULL; ++block; @@ -1212,36 +1214,14 @@ static int isofs_read_level3_size(struct inode *ino= de) printk(KERN_NOTICE "iso9660: Corrupted directory entry in block %lu of = inode %llu\n", block, inode->i_ino); brelse(bh); - kfree(tmpde); return -EIO; } =20 + de_len =3D de->length[0]; block_saved =3D block; offset_saved =3D offset; offset +=3D de_len; =20 - /* Make sure we have a full directory entry */ - if (offset >=3D bufsize) { - int slop =3D bufsize - offset + de_len; - if (!tmpde) { - tmpde =3D kmalloc(256, GFP_KERNEL); - if (!tmpde) - goto out_nomem; - } - memcpy(tmpde, de, slop); - offset &=3D bufsize - 1; - block++; - brelse(bh); - bh =3D NULL; - if (offset) { - bh =3D sb_bread(inode->i_sb, block); - if (!bh) - goto out_noread; - memcpy((void *)tmpde+slop, bh->b_data, offset); - } - de =3D tmpde; - } - inode->i_size +=3D isonum_733(de->size); if (i =3D=3D 1) { ei->i_next_section_block =3D block_saved; @@ -1255,17 +1235,11 @@ static int isofs_read_level3_size(struct inode *ino= de) goto out_toomany; } while (more_entries); out: - kfree(tmpde); brelse(bh); return 0; =20 -out_nomem: - brelse(bh); - return -ENOMEM; - out_noread: printk(KERN_INFO "ISOFS: unable to read i-node block %lu\n", block); - kfree(tmpde); return -EIO; =20 out_toomany: --=20 2.55.0