From: Shaurya Rane When read_cache_folio() is called with a NULL filler function on a mapping that doesn't implement read_folio, a NULL pointer dereference occurs in filemap_read_folio(). The crash occurs when: 1. build_id_parse() is called on a VMA backed by a file from a filesystem that doesn't implement address_space_operations.read_folio (e.g., procfs, sysfs, or other virtual filesystems) 2. read_cache_folio() is called with filler=NULL 3. do_read_cache_folio() sets filler = mapping->a_ops->read_folio (still NULL) 4. filemap_read_folio() calls filler() causing a NULL pointer dereference The fix is to add a NULL check after the fallback assignment and return -EIO, which is handled gracefully by the callers. Reported-by: syzbot+09b7d050e4806540153d@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=09b7d050e4806540153d Fixes: ad41251c290d ("lib/buildid: implement sleepable build_id_parse() API") Signed-off-by: Shaurya Rane --- Changes in v2: - Add early read_folio check in __build_id_parse() for unsupported filesystems. -Add defensive !filler check in do_read_cache_folio() to prevent NULL dereference. --- lib/buildid.c | 3 +++ mm/filemap.c | 2 ++ 2 files changed, 5 insertions(+) diff --git a/lib/buildid.c b/lib/buildid.c index c4b0f376fb34..3136cc92010f 100644 --- a/lib/buildid.c +++ b/lib/buildid.c @@ -298,6 +298,9 @@ static int __build_id_parse(struct vm_area_struct *vma, unsigned char *build_id, /* only works for page backed storage */ if (!vma->vm_file) return -EINVAL; + /* check if filesystem supports page cache operations */ + if (!vma->vm_file->f_mapping->a_ops->read_folio) + return -EINVAL; freader_init_from_file(&r, buf, sizeof(buf), vma->vm_file, may_fault); diff --git a/mm/filemap.c b/mm/filemap.c index 13f0259d993c..f700fe931d61 100644 --- a/mm/filemap.c +++ b/mm/filemap.c @@ -3980,6 +3980,8 @@ static struct folio *do_read_cache_folio(struct address_space *mapping, if (!filler) filler = mapping->a_ops->read_folio; + if (!filler) + return ERR_PTR(-EIO); repeat: folio = filemap_get_folio(mapping, index); if (IS_ERR(folio)) { -- 2.34.1