From nobody Sat Feb 7 17:09:26 2026 Received: from mail-pl1-f174.google.com (mail-pl1-f174.google.com [209.85.214.174]) (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 1F2A835E54F for ; Fri, 30 Jan 2026 12:40:00 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.174 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1769776801; cv=none; b=Y0/ErSwS5W64E/QAdrmBvBW1j/gGdQJeS7naisQhu/NGJkg5/G2KhdyfOTmgt1Qbw/JiQRUgYyFAdLMDOvkeese1wmY4gTep28i85ymW+3ahPWJzYY+XlqLxM573GxrrPnQwU2uX4aag2bQf6cr8vOKX46EFa8B2dxJYQnFN12U= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1769776801; c=relaxed/simple; bh=3BZc3Thv5LEKtK+rwOEodZllTHTFApthvFLc2lbPNNs=; h=From:To:Cc:Subject:Date:Message-ID:MIME-Version; b=Rz1WocvqZv5mTa4+BJk8GokpNJStnqU6PHE1dxtRuH04eH+sgiV6FpKdGj6Ema2S0Qb9MNkrtdXjcfHeGgSjg13Qmoi/3G64iVvAifU9a78I+5uUaPqcRIu6RNLP2UA1e8fpLxB+m/c3eIeq8lrGXWrcunmIbvqFoPI6fU2jzf4= 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=YNyNHZZT; arc=none smtp.client-ip=209.85.214.174 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="YNyNHZZT" Received: by mail-pl1-f174.google.com with SMTP id d9443c01a7336-2a0d67f1877so13424855ad.2 for ; Fri, 30 Jan 2026 04:40:00 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1769776799; x=1770381599; 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=IKEkl8CvxvFJM2weLeokDtwNfyW3MjqMZBwUQAOABKg=; b=YNyNHZZTl5cbZNG+8ewa6toouYCcBoys472z3o71Nl5esjU+GVDGdxdUqQSV3xLbJj Jgx1aypRpm4K5Y0NzVx1xKxys3ufgF8XNMMljgPlmZtHVQtgu4bTscCY2qkkzy1RZnMs R0pVuptMaj7dX26+7HcBojiuDVQ8OZ8Gv/xfriO5v2N/w+VjOX0ORTUEyENWoJ8D4Iyx 6KpBREOD5ogf3Nufm+JbExmj+jsrNXnSZ6Zi0eYpuclagxBO0m6y+OIQAYiQFhx0/s3d 25fKsX2+crqgICsrl5sVR4uYLlYDB/fm+N0hrVCTfwsJMWsNJqSsyhP4UbZ2DDMIaeVN tZTQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1769776799; x=1770381599; 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=IKEkl8CvxvFJM2weLeokDtwNfyW3MjqMZBwUQAOABKg=; b=YyYUFh3+y4thVFCT7t6cfc9uctmcCifI0cUjWZ+0GKFH3vrOa3q/O/cIAg/du97KkO r3p9vcbyCYB2BkXwzbf0Kpp8tBV341BX13YOThuPVXYGt1j72flGSeznWSunrdMqDbpa CmyFMGO4U+jGi3gK6XjR3kE2cdVReldsXPI6b4x973Gkdn4TSW8+EWNEDUy8aDeerHCa CP1UvufULJCmEWdBQrDy+fRz5se6CZenFvtfkxIlJbkQsz3SlLFBUw7sa6e8nriJC76w 87aB6xEpJkm2Wfoh+06kb78UhdkKuX6r7DaYGihuusMpTK+pf7J2Pd+3RUNP57dwqQYK BWNQ== X-Forwarded-Encrypted: i=1; AJvYcCVnFY2GTEs+llh32W/JMOo0neQ1cD+66bQlGyNAPOfaqDDK3uUFmi+r4lNTQ3JHnHSiLls6Rf9QV9OVGNc=@vger.kernel.org X-Gm-Message-State: AOJu0YzIfFmCfnsMuvY06nvt/VN5YFnvUFMI2tWtBrGl9X/wcBufntd0 sSlm6AqmIG0il/57G9pEZ7B2Dj6AqCFhbK2qXMemGeEgRQBZkhdmBQiGW1sQGg== X-Gm-Gg: AZuq6aJDKF0lzaEn7prJt2xdPSa8ycwOrKbYiyaKD+T4+hRs1D437ZeE+2TQ8e+8Gm5 UtU0DXGUjOByPI1eO1IAlxftPKKM6QLme/Izsc+xEQp2NPeKliwjPJqM1Rz3Wrxxp67yScBEGtm MMeSJN/HEjjQ9hmFcWMuCfaiaWKrvDKZmdU1ylHXT5JVdA/plI+XQchhzV2ebK3sYWT/xeknIQ2 l7IBvutxOWI3KJcuXDYmACUidXLblC/3eSvatlDIoHOvlKxw6h2viVSNc2g/GD86MUsNnq+fDKh mZIMbwMxYZZ1qzUUeD9A4lL8aTPZCNedlvz6aUqVspkEDV35CB9WFR1hd+vP1Htxq7lEeEEPtf+ F7wdGWfnmt2k8xVBM0SbBaJysgMKvxAktjSUzKbteXzRuK8sgeXwKfmWoN6iG5g1n2pawYqiWuz tRjGNmABcAyvAfRidQVD6YoiUgS7MaG14TapwpjjTuk04CNNdPkLSlVLmMlQ1wArwFrGxNNxHt6 MurGw== X-Received: by 2002:a17:903:2f0b:b0:2a7:9163:8e68 with SMTP id d9443c01a7336-2a8d7eabffamr31847535ad.6.1769776799459; Fri, 30 Jan 2026 04:39:59 -0800 (PST) Received: from deepanshu-kernel-hacker.. ([2405:201:682f:389d:144b:d627:2937:e2fe]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-82379c64b4esm8247169b3a.69.2026.01.30.04.39.56 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 30 Jan 2026 04:39:58 -0800 (PST) From: Deepanshu Kartikey To: agruenba@redhat.com Cc: gfs2@lists.linux.dev, linux-kernel@vger.kernel.org, Deepanshu Kartikey , syzbot+ea1cd4aa4d1e98458a55@syzkaller.appspotmail.com Subject: [PATCH v2] gfs2: Fix use-after-free and reference leaks in iomap inline data paths Date: Fri, 30 Jan 2026 18:09:51 +0530 Message-ID: <20260130123951.64927-1-kartikey406@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: quoted-printable Content-Type: text/plain; charset="utf-8" The inline data buffer head (dibh) is being released prematurely in gfs2_iomap_begin() via release_metapath(), while iomap->inline_data still points to dibh->b_data. This causes a use-after-free when iomap_write_end_inline() later attempts to write to the inline data area. Additionally, gfs2_iomap_get() and gfs2_iomap_alloc() leak buffer head references when they call __gfs2_iomap_get() for inline data files, as they don't release the dibh reference stored in iomap->private. The bug sequence for the use-after-free: 1. __gfs2_iomap_get() calls gfs2_meta_inode_buffer() to read inode metadata into dibh 2. Sets iomap->inline_data =3D dibh->b_data + sizeof(struct gfs2_dinode) 3. Calls release_metapath() which calls brelse(dibh), dropping refcount to 0 4. kswapd reclaims the page (~39ms later in the syzbot report) 5. iomap_write_end_inline() tries to memcpy() to iomap->inline_data 6. KASAN detects use-after-free write to freed memory Fix by storing dibh in iomap->private and incrementing its refcount with get_bh() in __gfs2_iomap_get(). The buffer is then properly released in: - gfs2_iomap_end() for the iomap iterator path - gfs2_iomap_get() before returning - gfs2_iomap_alloc() before returning This ensures the page stays alive for the entire iomap operation and prevents reference leaks. Changes in v2: - Simplified iomap->private cleanup in gfs2_iomap_end() per feedback from Andreas Gruenbacher (removed redundant type check and explicit NULL assignment) - Added missing brelse(iomap->private) in gfs2_iomap_get() to fix buffer head reference leak - Added missing brelse(iomap->private) in gfs2_iomap_alloc() to fix buffer head reference leak Note: A C reproducer is not available for this issue. The fix is based on analysis of the KASAN report and code review. Reported-by: syzbot+ea1cd4aa4d1e98458a55@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=3Dea1cd4aa4d1e98458a55 Signed-off-by: Deepanshu Kartikey --- fs/gfs2/bmap.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/fs/gfs2/bmap.c b/fs/gfs2/bmap.c index 131091520de6..81a958694d1f 100644 --- a/fs/gfs2/bmap.c +++ b/fs/gfs2/bmap.c @@ -887,6 +887,8 @@ static int __gfs2_iomap_get(struct inode *inode, loff_t= pos, loff_t length, sizeof(struct gfs2_dinode); iomap->type =3D IOMAP_INLINE; iomap->inline_data =3D dibh->b_data + sizeof(struct gfs2_dinode); + iomap->private =3D dibh; + get_bh(dibh); goto out; } =20 @@ -1144,6 +1146,9 @@ static int gfs2_iomap_end(struct inode *inode, loff_t= pos, loff_t length, struct gfs2_inode *ip =3D GFS2_I(inode); struct gfs2_sbd *sdp =3D GFS2_SB(inode); =20 + if (iomap->private) + brelse(iomap->private); + switch (flags & (IOMAP_WRITE | IOMAP_ZERO)) { case IOMAP_WRITE: if (flags & IOMAP_DIRECT) @@ -1419,6 +1424,8 @@ int gfs2_iomap_get(struct inode *inode, loff_t pos, l= off_t length, =20 ret =3D __gfs2_iomap_get(inode, pos, length, 0, iomap, &mp); release_metapath(&mp); + if (iomap->private) + brelse(iomap->private); return ret; } =20 @@ -1432,6 +1439,8 @@ int gfs2_iomap_alloc(struct inode *inode, loff_t pos,= loff_t length, if (!ret && iomap->type =3D=3D IOMAP_HOLE) ret =3D __gfs2_iomap_alloc(inode, iomap, &mp); release_metapath(&mp); + if (iomap->private) + brelse(iomap->private); return ret; } =20 --=20 2.43.0