public inbox for linux-fsdevel@vger.kernel.org
 help / color / mirror / Atom feed
From: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
To: George Vernon <contact@gvernon.com>,
	Viacheslav Dubeyko <Slava.Dubeyko@ibm.com>
Cc: syzbot+97e301b4b82ae803d21b@syzkaller.appspotmail.com,
	glaubitz@physik.fu-berlin.de, frank.li@vivo.com,
	slava@dubeyko.com, linux-kernel@vger.kernel.org,
	linux-fsdevel@vger.kernel.org
Subject: Re: [PATCH v4] hfs: Validate CNIDs in hfs_read_inode
Date: Fri, 20 Mar 2026 09:32:12 +0900	[thread overview]
Message-ID: <9f66743b-70e0-4886-884e-5203f5c02ed8@I-love.SAKURA.ne.jp> (raw)
In-Reply-To: <070d92639460b672a174d6a11b1e7d0b099b18cb@gvernon.com>

On 2026/03/19 21:26, George Vernon wrote:
> March 19, 2026 at 9:57 AM, "Tetsuo Handa" <penguin-kernel@i-love.sakura.ne.jp mailto:penguin-kernel@i-love.sakura.ne.jp?to=%22Tetsuo%20Handa%22%20%3Cpenguin-kernel%40i-love.sakura.ne.jp%3E > wrote:
> 
> 
>>
>> On 2026/03/19 7:49, George Anthony Vernon wrote:
>>
>>>
>>> Tetsuo, what do you think about doing your check inside
>>>  hfs_cat_find_brec? Something a bit like this:
>>>
>> Currently hfs_cat_find_brec() is called by only hfs_fill_super()
>> with cnid == HFS_ROOT_CNID. Are you planning to add more callers?
>>
>> If no, my patch
>>
>>  - if (rec.type != HFS_CDR_DIR)
>>  + if (rec.type != HFS_CDR_DIR || rec.dir.DirID != cpu_to_be32(HFS_ROOT_CNID))
>>
>> is sufficient.
> 
> I'm trying to write a patch Slava will accept, maybe I didn't fully understand
> what he wanted but I think he wanted to fix hfs_cat_find_brec() so it should not
> return an incorrect cat record.

Neither do I understand. Is the diff below what Viacheslav Dubeyko wants?

 fs/hfs/catalog.c |   26 ++++++++++++++++----------
 fs/hfs/hfs_fs.h  |    4 ++--
 fs/hfs/super.c   |   11 +----------
 3 files changed, 19 insertions(+), 22 deletions(-)

diff --git a/fs/hfs/catalog.c b/fs/hfs/catalog.c
index 7f5339ee57c1..e24fe49d5850 100644
--- a/fs/hfs/catalog.c
+++ b/fs/hfs/catalog.c
@@ -184,31 +184,37 @@ int hfs_cat_keycmp(const btree_key *key1, const btree_key *key2)
 
 /* Try to get a catalog entry for given catalog id */
 // move to read_super???
-int hfs_cat_find_brec(struct super_block *sb, u32 cnid,
-		      struct hfs_find_data *fd)
+int hfs_cat_find_root_brec(struct super_block *sb, struct hfs_find_data *fd, hfs_cat_rec *rec)
 {
-	hfs_cat_rec rec;
 	int res, len, type;
 
-	hfs_cat_build_key(sb, fd->search_key, cnid, NULL);
-	res = hfs_brec_read(fd, &rec, sizeof(rec));
+	hfs_cat_build_key(sb, fd->search_key, HFS_ROOT_CNID, NULL);
+	res = hfs_brec_read(fd, rec, sizeof(*rec));
 	if (res)
 		return res;
 
-	type = rec.type;
+	type = rec->type;
 	if (type != HFS_CDR_THD && type != HFS_CDR_FTH) {
 		pr_err("found bad thread record in catalog\n");
 		return -EIO;
 	}
 
-	fd->search_key->cat.ParID = rec.thread.ParID;
-	len = fd->search_key->cat.CName.len = rec.thread.CName.len;
+	fd->search_key->cat.ParID = rec->thread.ParID;
+	len = fd->search_key->cat.CName.len = rec->thread.CName.len;
 	if (len > HFS_NAMELEN) {
 		pr_err("bad catalog namelength\n");
 		return -EIO;
 	}
-	memcpy(fd->search_key->cat.CName.name, rec.thread.CName.name, len);
-	return hfs_brec_find(fd);
+	memcpy(fd->search_key->cat.CName.name, rec->thread.CName.name, len);
+	res = hfs_brec_find(fd);
+	if (res)
+		return res;
+	if (fd->entrylength != sizeof(rec->dir))
+		return -EIO;
+	hfs_bnode_read(fd->bnode, rec, fd->entryoffset, sizeof(rec->dir));
+	if (rec->type != HFS_CDR_DIR || rec->dir.DirID != cpu_to_be32(HFS_ROOT_CNID))
+		return -EIO;
+	return 0;
 }
 
 static inline
diff --git a/fs/hfs/hfs_fs.h b/fs/hfs/hfs_fs.h
index ac0e83f77a0f..46641b60913f 100644
--- a/fs/hfs/hfs_fs.h
+++ b/fs/hfs/hfs_fs.h
@@ -145,8 +145,8 @@ extern int hfs_clear_vbm_bits(struct super_block *sb, u16 start, u16 count);
 /* catalog.c */
 extern int hfs_cat_keycmp(const btree_key *key1, const btree_key *key2);
 struct hfs_find_data;
-extern int hfs_cat_find_brec(struct super_block *sb, u32 cnid,
-			     struct hfs_find_data *fd);
+extern int hfs_cat_find_root_brec(struct super_block *sb, struct hfs_find_data *fd,
+				  hfs_cat_rec *rec);
 extern int hfs_cat_create(u32 cnid, struct inode *dir,
 			  const struct qstr *str, struct inode *inode);
 extern int hfs_cat_delete(u32 cnid, struct inode *dir, const struct qstr *str);
diff --git a/fs/hfs/super.c b/fs/hfs/super.c
index 2e52acf282b0..c0be872d4079 100644
--- a/fs/hfs/super.c
+++ b/fs/hfs/super.c
@@ -354,16 +354,7 @@ static int hfs_fill_super(struct super_block *sb, struct fs_context *fc)
 	res = hfs_find_init(HFS_SB(sb)->cat_tree, &fd);
 	if (res)
 		goto bail_no_root;
-	res = hfs_cat_find_brec(sb, HFS_ROOT_CNID, &fd);
-	if (!res) {
-		if (fd.entrylength != sizeof(rec.dir)) {
-			res =  -EIO;
-			goto bail_hfs_find;
-		}
-		hfs_bnode_read(fd.bnode, &rec, fd.entryoffset, fd.entrylength);
-		if (rec.type != HFS_CDR_DIR || rec.dir.DirID != cpu_to_be32(HFS_ROOT_CNID))
-			res = -EIO;
-	}
+	res = hfs_cat_find_root_brec(sb, &fd, &rec);
 	if (res)
 		goto bail_hfs_find;
 	res = -EINVAL;


  reply	other threads:[~2026-03-20  1:13 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-03-11 21:13 [PATCH v4] hfs: Validate CNIDs in hfs_read_inode George Anthony Vernon
2026-03-12 10:45 ` Tetsuo Handa
2026-03-12 23:13   ` Viacheslav Dubeyko
2026-03-13 11:03     ` Tetsuo Handa
2026-03-13 18:40       ` Viacheslav Dubeyko
2026-03-14  6:35         ` Tetsuo Handa
2026-03-16 21:50           ` Viacheslav Dubeyko
2026-03-18  0:37             ` George Anthony Vernon
2026-03-18  2:02               ` Viacheslav Dubeyko
2026-03-18 22:49                 ` George Anthony Vernon
2026-03-19  9:57                   ` Tetsuo Handa
2026-03-19 12:26                     ` George Vernon
2026-03-20  0:32                       ` Tetsuo Handa [this message]
2026-03-18 10:42             ` Tetsuo Handa
2026-03-18  0:10   ` George Anthony Vernon
2026-03-18  8:16     ` Tetsuo Handa
2026-03-12 23:07 ` Viacheslav Dubeyko

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=9f66743b-70e0-4886-884e-5203f5c02ed8@I-love.SAKURA.ne.jp \
    --to=penguin-kernel@i-love.sakura.ne.jp \
    --cc=Slava.Dubeyko@ibm.com \
    --cc=contact@gvernon.com \
    --cc=frank.li@vivo.com \
    --cc=glaubitz@physik.fu-berlin.de \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=slava@dubeyko.com \
    --cc=syzbot+97e301b4b82ae803d21b@syzkaller.appspotmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox