From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-pl1-f178.google.com (mail-pl1-f178.google.com [209.85.214.178]) (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 54A8E433E9B for ; Tue, 14 Jul 2026 23:54:14 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.178 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784073255; cv=none; b=afupavmvpwMZuJZIsnccpxwh1IyWJx1Ta5V1Lm5Zx2Aor4VF+9P0Oloeji0NOUaBRMJi2UVUXxguDgQog9Pa4G3Jw52Ijq8XfG4PR+ol0fvg47G805mZz6mEmVuMa3bizT7G03lz9BdPguC+ABMZz9qNcG8bU0tJEQLqiM4jl1M= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784073255; c=relaxed/simple; bh=iWC3dwTVFS0On/b+U1UVC9eFIiIpL6Q6Bi+esX7/UyE=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=aSm3QIx7Oxx7iIeoJSvIUrmWOYUfySLMtQt9qviXj60M7IH2+OUQx+zbuJUA0qa0mfDZK6RTVTjsYTTJNyOE36xAR1bIv+oRehp4EckQDdF0iwCpaF3i878su/FeuCwtBurXoJVvp/RhjIA/VMj7bNC31WxuR2FyeGF47RQIzHk= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=asu.edu; spf=pass smtp.mailfrom=asu.edu; dkim=pass (2048-bit key) header.d=asu.edu header.i=@asu.edu header.b=Waxb25M6; arc=none smtp.client-ip=209.85.214.178 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=asu.edu Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=asu.edu Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=asu.edu header.i=@asu.edu header.b="Waxb25M6" Received: by mail-pl1-f178.google.com with SMTP id d9443c01a7336-2cad4170e8eso59067005ad.3 for ; Tue, 14 Jul 2026 16:54:14 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=asu.edu; s=google; t=1784073254; x=1784678054; 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=1yNKCuh3wjjGZi+YwPUxJXNIOv8IEH+SL77HN2XtO6I=; b=Waxb25M6IpUWOTf4MJHsEpkppvNwqv5/i+Rk9c4uvwoK9782PALi0veiQUU7O76nT2 0V3AK64/Wmqp7K8OE7WfDhxaj3VW/gYBcRVjkN+VM/Fn7Ja1eGeq2Fgg3kFambXfGMAv VkZH7gtQRIVTqftUPHAGJj3we87RcDTSoPbvvi3QkHIfeyvaTHUY74sueVuj8NhAgR1T w/8Z7h0WLWlIezrhd2n18pWMM7m9izxQ5wkH4KTvSVf1YQd+XS37d+CO9JzEIGLOqC0o 2XrjFl+EIV1PlJx5ZvzSq3n6IJZ/Ul47j3hzCx4mJUos7WmuO0CpoE8tOVqwxIoR7XST zg4A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1784073254; x=1784678054; 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=1yNKCuh3wjjGZi+YwPUxJXNIOv8IEH+SL77HN2XtO6I=; b=EXEOiJ4186mzvHIFbEJQTp5V47oPEH2SxFVAzIacWFIUuJvnIDwK8+ZODfsDccjUhB yRyw/8NL691JXfGtYljN0Kjz/iVfrG+IeR+LTbLbiImtvFSFV0A4lfAjH0nwaYMG9evh Fu+g1aTQb9OAK6XRHAwNh/WM3EyFvKcM3H4aLkxsbN6WXNIiMR0kZX/m9lh9B26iv5yn u7QRGlT+r51V7rWWTRkYjTJSfLx58+W/CdKUvu5cncVbFigrx5kkzLpS4fq8VHdMpNUb v6nY80DoShAXHcJ6U04xsXrFvK2Z7+oxsHHGZD7Pb3YlSSYI43Lk5owLaqxHtYbax8Ye R+Fw== X-Forwarded-Encrypted: i=1; AHgh+RqNQUPkduuz0drVloLmU1GyNNekl/LMuUcCSGueqYEWfoUfV1rw8gkk4nGNplNkWxSJP1pHGO1zCBgEEKU=@vger.kernel.org X-Gm-Message-State: AOJu0YwccdvUMVsCCgLrsnslfVGF2b480wYx6DhnRN2apv4V7bgLA29g WTirk9VyFlkgJGLhRMAKw56R7FLS8maag2a5aCmOUdSMYU2j06ChuU4b6hnPP9LTww== X-Gm-Gg: AfdE7cmlDhwfR9d78ZKgEkIPEEgMZwXs2wjkmceGzuhw6t3vBf3lO9Wj8CY1QOW8ZAT E4kt3P+RP+i9imgSI1YujVcxXzGrvv4I9p6NDr13CmEMIbnSifhneUJor2KCfXWHdv0NHEW1Rsm zPisIyS/KvtOAThg3gJu0CWcv6dunKJYyzl7uYPCXqQk+jDzbBUDNM0EoUpWrWdzP7R0b5RSIWj uFsGR+jDNH97ssW+tAODjLmmWOJ+UIlU8ODivx+XEZFIAjUsD0RRJEUP9kdiA0/poGA/T19oq9m VVSmflxsc9eI/CW1SX4in988aEkcAgAG6JhWLw8ekdDUePiFkVeaksBmr8qimtOhAawhB/LKvkc 334WCNz6OEvyqZ0SEPtZKyG9JjnSw5nQAGMdrzI+IO81CTdW8RL1F6FN06eXnR8FTgz2ixgU1lA == X-Received: by 2002:a17:903:380f:b0:2c9:c18f:7446 with SMTP id d9443c01a7336-2cef143b0aemr46392065ad.27.1784073253712; Tue, 14 Jul 2026 16:54:13 -0700 (PDT) Received: from p1.. ([2607:fb91:1513:463e:34c6:f6a3:8e91:2983]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-2ccc9d3d451sm123236075ad.65.2026.07.14.16.54.12 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 14 Jul 2026 16:54:13 -0700 (PDT) From: Xiang Mei To: Joanne Koong , Bernd Schubert , Baokun Li , Miklos Szeredi , Kees Cook , "Gustavo A . R . Silva" Cc: fuse-devel@lists.linux.dev, linux-hardening@vger.kernel.org, linux-kernel@vger.kernel.org, stable@vger.kernel.org, Luis Henriques , Pavel Begunkov , bestswngs@gmail.com, Xiang Mei Subject: [PATCH v4 2/3] fuse: bound io-uring payload copies to the registered buffer size Date: Tue, 14 Jul 2026 16:54:07 -0700 Message-ID: <20260714235408.1666063-2-xmei5@asu.edu> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260714235408.1666063-1-xmei5@asu.edu> References: <20260714235408.1666063-1-xmei5@asu.edu> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit The fuse-io-uring transport imports each ring entry's payload buffer at ring->max_payload_sz and bounds both copy directions against that value, ignoring the buffer length the server actually registered. Both the server-supplied reply payload_sz (fuse_uring_copy_from_ring) and an oversized request payload such as a large FUSE_SETXATTR value (fuse_uring_args_to_ring) can then overrun the imported iterator and hit fuse_copy_fill()'s BUG_ON(!err): kernel BUG at fs/fuse/dev.c:1053! Oops: invalid opcode: 0000 [#1] SMP KASAN NOPTI RIP: 0010:fuse_copy_fill (fs/fuse/dev.c:1022) Call Trace: fuse_copy_args (fs/fuse/dev.c:1329 fs/fuse/dev.c:1351) fuse_uring_copy_from_ring (fs/fuse/dev_uring.c:686) fuse_uring_cmd (fs/fuse/dev_uring.c:1226) io_uring_cmd (io_uring/uring_cmd.c:271) __io_issue_sqe (io_uring/io_uring.c:1395) io_issue_sqe (io_uring/io_uring.c:1418) io_submit_sqes (io_uring/io_uring.c:1649 io_uring/io_uring.c:1934 io_uring/io_uring.c:2057) __do_sys_io_uring_enter (io_uring/io_uring.c:2646) do_syscall_64 (arch/x86/entry/syscall_64.c:63 arch/x86/entry/syscall_64.c:94) entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:121) The request path overruns the same way, via fuse_copy_args() -> fuse_uring_args_to_ring(). Store the registered payload length (payload->iov_len) in the ring entry and use it for the import and both bounds checks, so the buffer the server provided is honoured and an oversized reply/request is rejected (-EINVAL for a reply, and -E2BIG/-EIO for a request, matching fuse_dev_do_read()) instead of panicking. Fixes: c090c8abae4b ("fuse: Add io-uring sqe commit and fetch support") Cc: stable@vger.kernel.org Reported-by: Weiming Shi Assisted-by: Claude:claude-opus-4-8 Signed-off-by: Xiang Mei Reviewed-by: Joanne Koong --- v3: propose the patch fixing another issue found by Bernd by Joanne suggested way v4: no context change as v3; add Reviewed-by: Joanne Koong ... fs/fuse/dev_uring.c | 9 ++++++++- fs/fuse/dev_uring_i.h | 1 + 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/fs/fuse/dev_uring.c b/fs/fuse/dev_uring.c index 77c8cec43d9c..4529505b2bca 100644 --- a/fs/fuse/dev_uring.c +++ b/fs/fuse/dev_uring.c @@ -650,7 +650,7 @@ static int setup_fuse_copy_state(struct fuse_copy_state *cs, { int err; - err = import_ubuf(dir, ent->payload, ring->max_payload_sz, iter); + err = import_ubuf(dir, ent->payload, ent->payload_sz, iter); if (err) { pr_info_ratelimited("fuse: Import of user buffer failed\n"); return err; @@ -679,6 +679,9 @@ static int fuse_uring_copy_from_ring(struct fuse_ring *ring, if (err) return err; + if (ring_in_out.payload_sz > ent->payload_sz) + return -EINVAL; + err = setup_fuse_copy_state(&cs, ring, req, ent, ITER_SOURCE, &iter); if (err) return err; @@ -725,6 +728,9 @@ static int fuse_uring_args_to_ring(struct fuse_ring *ring, struct fuse_req *req, num_args--; } + if (fuse_len_args(num_args, (struct fuse_arg *)in_args) > ent->payload_sz) + return args->opcode == FUSE_SETXATTR ? -E2BIG : -EIO; + /* copy the payload */ err = fuse_copy_args(&cs, num_args, args->in_pages, (struct fuse_arg *)in_args, 0); @@ -1159,6 +1165,7 @@ fuse_uring_create_ring_ent(struct io_uring_cmd *cmd, ent->queue = queue; ent->headers = headers->iov_base; ent->payload = payload->iov_base; + ent->payload_sz = payload->iov_len; atomic_inc(&ring->queue_refs); return ent; diff --git a/fs/fuse/dev_uring_i.h b/fs/fuse/dev_uring_i.h index 55f8d04e4b0b..efa7f034496a 100644 --- a/fs/fuse/dev_uring_i.h +++ b/fs/fuse/dev_uring_i.h @@ -41,6 +41,7 @@ struct fuse_ring_ent { /* userspace buffer */ struct fuse_uring_req_header __user *headers; void __user *payload; + size_t payload_sz; /* the ring queue that owns the request */ struct fuse_ring_queue *queue; -- 2.43.0