From nobody Mon May 25 04:33:48 2026 Received: from mail-ed1-f52.google.com (mail-ed1-f52.google.com [209.85.208.52]) (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 33E58382F08 for ; Mon, 18 May 2026 18:26:09 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.208.52 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779128770; cv=none; b=mFFtzqflR8ZcD2VRjPVnm7HtXVpPVwQGyeqqhR+0Uv5xIHJ2KuMK5jmxrr9l+5jkwanAZFunpTriE/6gh6F/2TZREXSgeeDgEgxSgfNuVXZE1D458HkFJ2LQgal1oIAlKb8w6MLlKLescytXuV03v5CJhBIfU42eolZxwgUXyg0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779128770; c=relaxed/simple; bh=AJQ8X8vekQbsX2A2arXJ8CBDC1jAwqSdrm7rYzzgrNs=; h=From:To:Cc:Subject:Date:Message-ID:MIME-Version; b=cEbgQ9QNnbKvDSu28n/R/xhggRUUZlyJQY6iYE9nBMvq+kCEzD+cclE56e8xHYXbSmuD79XvfHOs6Z7H6av6BEe73w7oYQGGlioc9PL723Yw2jRR02vo7FhVTkc6iCe98kMX2OSiiRtcth/SUdwKfUh03nJEaw7LyN+u0IGgvhg= 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=GEOOYRjr; arc=none smtp.client-ip=209.85.208.52 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="GEOOYRjr" Received: by mail-ed1-f52.google.com with SMTP id 4fb4d7f45d1cf-67e43a8996fso3334385a12.0 for ; Mon, 18 May 2026 11:26:08 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1779128767; x=1779733567; 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=fjppO2+PwKNhaclh25OQ0CMNeNNbO/jvr0ag7TFBQ9k=; b=GEOOYRjr7jabRzKpTfVGB0uROawVxK9+gZC7t6JzLZuza8bI8fA5GU8No9N5/RJD4q /nYGbgo2h5IBgIRtLW7/+0KGvVAmcSPNAp4MC9y840M2z6OfodXPqgs3yzflzxjcOVbm O6dt8LJQLosfx+DPnFjPEc4iw70Rjuo93T+B2IaCFFoak8Ccs17MGNtHvC4sDZ2Jvbaz PCuJdzzLKpCwByYP6F+9CwTmfsh7bGEnxviW2j8E3GZhiRaKjnFYaRlHAh/s+G4Bsy39 QXYiUT5qrmafgcv1hdLCmmXP121m3c+d9MH17sCgnpLDZj+23cApWZjF5eLktsqNFjJO MwLw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1779128767; x=1779733567; 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=fjppO2+PwKNhaclh25OQ0CMNeNNbO/jvr0ag7TFBQ9k=; b=EyhMaww+cumrOPKSv4yD2kPDS1SoHgrCy0Y3cu0l5E86FeZFix2/feKvPzvM4dDYLU uUX+ZoNdw2Y18YCeMtqkPto8kG86y4DTwKcIvVrIYQf4qY+ll/Lch+cck87t7hGUtyiS 3Y3opCE0l9bobSIv9qWNqevsQe7x5o2LHDQnJgYKevtIpNJVENID8w46hZDzN9Iq8g+6 Ys1vHFSgqQa85WQr3G/YXK++vE3t+o9mrJegr6g+XoTwvITWyKCg958XkfL2iftgjTGX zapOpUodpdxylM0zej6CXO99CACYwumgeQjJnY5GVnrLtruex1qEbrZOYpVzgfm98nkw tFDA== X-Forwarded-Encrypted: i=1; AFNElJ9oLKswoa7SZbgisEz56O5sNoJ45xDwUJKVHZdLTk54+Pw/FVOswTKripDHl0OxUt/EXiJDaIEkiONIQS0=@vger.kernel.org X-Gm-Message-State: AOJu0Yww6BNY1gR8jj8RutQHdMUGvtVaP5A9r6WBuKb5+4yYY2Hn8gtD ujjK27eomDsGLVeE8E/i/4rU+MK/gUgKZI7idf6lXU1/4VU2uUka8xzi X-Gm-Gg: Acq92OGe7NU9wUwX2t3NqHB5EF4VHyXhwZeDQ7jozCf3TFKCdjD5G5gCz2/qjid9ogr 3McNhCsElnMIryO/cmBRAFVg/n3gv2ZsHJxqaEJzri/0E26r0yRo0Fckrw2yfqrQ6dVumPz8eS/ Jmkzms8KgfZ6dDQ+8q+V6dyy0g7iAp1XjCfkazZc+LvvGw9fXa+5VGdZqIr1Zp4ZJNrvTKspsN5 OKdfPUVo8m1BfHL2NqCI96XOk27CW23ZBZuvXWy83OSnvws6iEQDTkFD0HiwRAkbYBxp4XwUUs8 BlWfKTfLdkmvg6umSF3YVFhh4rCfFIlj5pX3xrhiWagBBDCnQUcgTI8+vIIdfCvJ3IsnkrPB/gk E5Bq9RVGJqhdBoj9mvNqtdkQlQy8M5ym0XDyMxGJQabeslDXtmbyiGEIBByp92vJYgRD5RDEBQU t0SDI0gHiPwUZ8gxyT X-Received: by 2002:aa7:c652:0:b0:681:5b68:b26d with SMTP id 4fb4d7f45d1cf-683bc4b5ae7mr5810099a12.6.1779128767128; Mon, 18 May 2026 11:26:07 -0700 (PDT) Received: from localhost ([2a03:2880:32ff:70::]) by smtp.gmail.com with ESMTPSA id 4fb4d7f45d1cf-68310b3e973sm5691646a12.3.2026.05.18.11.26.04 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 18 May 2026 11:26:05 -0700 (PDT) From: Vlad Poenaru To: Miklos Szeredi Cc: Joanne Koong , Breno Leitao , Josef Bacik , linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, stable@vger.kernel.org Subject: [PATCH 6.18.y] fuse: avoid 0x10 fault in fuse_readahead when max_pages == 0 Date: Mon, 18 May 2026 11:26:02 -0700 Message-ID: <20260518182602.3107764-1-vlad.wing@gmail.com> X-Mailer: git-send-email 2.52.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" When fc->max_read is smaller than PAGE_SIZE (common on aarch64 with 64K base pages if the FUSE server advertises a small max_read in INIT), max_pages =3D min(fc->max_pages, fc->max_read / PAGE_SIZE) is 0, so cur_pages is 0 on every outer iteration. fuse_io_alloc(NULL, 0) then calls fuse_folios_alloc(0, ...), which calls kzalloc(0, ...) and gets back ZERO_SIZE_PTR =3D=3D (void *)16. The "if (!ia->ap.folios)" guard in fuse_io_alloc does not catch ZERO_SIZE_PTR, so fuse_io_alloc happily returns an ia whose ap.folios is 0x10. The inner "while (pages < cur_pages)" loop runs zero times, then fuse_send_readpages(ia, ...) dereferences ap->folios[0] in folio_pos(), faulting at virtual address 0x10: Unable to handle kernel NULL pointer dereference at virtual address 0000000000000010 fuse_readahead+0x14c/0x490 read_pages+0x80/0x318 page_cache_ra_unbounded+0x1c0/0x2b0 page_cache_ra_order+0xb8/0x368 page_cache_sync_ra+0x210/0x320 filemap_get_pages+0x290/0xdb0 generic_file_read_iter+0xd0/0x540 fuse_file_read_iter+0x8c/0x158 __arm64_sys_read+0x1a0/0x488 addr2line on the aarch64 vmlinux maps fuse_readahead+0x14c to fs/fuse/file.c:897 inlined into :999, i.e. "folio_pos(ap->folios[0])" inside fuse_send_readpages. The faulting instruction "ldr x8, [x8]" loads ap->folios[0]; ap->folios was previously loaded as 0x10 (ZERO_SIZE_PTR). Without this fix the function would also spin forever, since "nr_pages -=3D pages" makes no progress when pages stays 0; in practice the NULL deref masks the spin. Bail out of the outer loop if cur_pages is 0 -- there is no work we can issue via FUSE in this iteration, and remaining folios will be handled by read_pages() falling back to ->read_folio. Note: this code was rewritten in mainline by commit 4ea907108a5c ("fuse: use iomap for readahead"), which switched fuse_readahead to iomap and removed the buggy loop entirely. This patch therefore applies only to stable branches that still carry the pre-iomap readahead path. Fixes: 3eab9d7bc2f4 ("fuse: convert readahead to use folios") Reported-by: Breno Leitao Cc: stable@vger.kernel.org Signed-off-by: Vlad Poenaru --- fs/fuse/file.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/fs/fuse/file.c b/fs/fuse/file.c index 6014d588845c..782178124512 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c @@ -974,6 +974,16 @@ static void fuse_readahead(struct readahead_control *r= ac) unsigned cur_pages =3D min(max_pages, nr_pages); unsigned int pages =3D 0; =20 + /* + * If max_pages =3D=3D 0 (e.g. fc->max_read < PAGE_SIZE on a + * 64K-page kernel), cur_pages is 0 and we cannot make + * progress. Bailing here avoids passing 0 to fuse_io_alloc, + * which would return an ia whose ap.folios is ZERO_SIZE_PTR + * (0x10) -- later dereferenced by fuse_send_readpages. + */ + if (!cur_pages) + break; + if (fc->num_background >=3D fc->congestion_threshold && rac->ra->async_size >=3D readahead_count(rac)) /* --=20 2.53.0-Meta