From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-oa1-f44.google.com (mail-oa1-f44.google.com [209.85.160.44]) (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 DB8782DF701 for ; Wed, 17 Jun 2026 14:54:19 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.160.44 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1781708062; cv=none; b=jkuhceNxGUwfPbuenL36plg4BwVtWcnkzBg44h+16JC6VOGrOFsKkNLpvTj77MiBvljoqQnHBfQaKXAW7Uzsr8oK4upP9ixPPk4XQJVqAzz9ONqgkIqSqMb5A96tm5SXU/yvg61JK3PX4WdmFlpplHIjgGl+kEJpXK//lG4TFPQ= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1781708062; c=relaxed/simple; bh=JYvlfimKSqygNvWjrm0SJL/OntXTf5oSDKuVqv/4Qgc=; h=Message-ID:Date:MIME-Version:Subject:To:Cc:References:From: In-Reply-To:Content-Type; b=gNhHg3HDcAjXNDBvyRCX3ZNk8+FWEccGeWTp6coqqW0hehxKGCbNZnsXVLYdWC92F+cNLgbkMhWNtj901HeaAeIDdGSmQa1QoDgZxmBcTfQhteSv+gApB5eLx/7WMNu2NxjpF1hMoLp5/lA/hsKUsrVoynxSnsiHYVXsYFAyi2w= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=kernel.dk; spf=pass smtp.mailfrom=kernel.dk; dkim=pass (2048-bit key) header.d=kernel-dk.20251104.gappssmtp.com header.i=@kernel-dk.20251104.gappssmtp.com header.b=D9poun7u; arc=none smtp.client-ip=209.85.160.44 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=kernel.dk Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=kernel.dk Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel-dk.20251104.gappssmtp.com header.i=@kernel-dk.20251104.gappssmtp.com header.b="D9poun7u" Received: by mail-oa1-f44.google.com with SMTP id 586e51a60fabf-43cce7db292so4451383fac.2 for ; Wed, 17 Jun 2026 07:54:19 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel-dk.20251104.gappssmtp.com; s=20251104; t=1781708058; x=1782312858; darn=vger.kernel.org; h=content-transfer-encoding:in-reply-to:from:content-language :references:cc:to:subject:user-agent:mime-version:date:message-id :from:to:cc:subject:date:message-id:reply-to; bh=K8Wv7VCkyaLN0s61xd4QXGQ88sPTQ0XGFCHSINh9F+E=; b=D9poun7u32mr2DCGJwc6cMYl7qlGIpMo1ilH8qatgFINlnGlNBsz9S0NxGOKmqnXKR TZ1NYE8YGdPgPZMDRLU0jGicSav6uH7X9ML7lqwkohB2vhHQMdsko66hgHZ12efGtifk 8o5dx6sx5DU5Jf1wu4PqUHOL7km3rwARuWZXz847r6RNsOZxtSiEzUx6QCLyKX1JPcfN I5w2pk5ZcP9QQfIy+DS+OGz16gF6hEnAtdeCsUOyu+cMBliRJg8mcFyIMhVKZ0DeIRMA ZiuUf6/ljytzwY+4g1u+IeOax7aiA7yygB59215WNzVdhMNEEg2fdnx8Qjo5EgRRFRCp 74HQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1781708058; x=1782312858; h=content-transfer-encoding:in-reply-to:from:content-language :references:cc:to:subject:user-agent:mime-version:date:message-id :x-gm-gg:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=K8Wv7VCkyaLN0s61xd4QXGQ88sPTQ0XGFCHSINh9F+E=; b=iMCYHqg4/fyNysbY9BprlGBLzLv4Sbmh9OlHf9Q9KI4W26YhkqJQ5smKvhEhKF7VtJ I5BFFoIAlzRqwo/PHICbzw+2/7CY1myPtwifpwxV9xw40yN0Vaiaa6NyVuhRes57pBe8 v5iFbSqV9sfnpNJEgBnRKF6847P/YPPz6MATsvI4h0eBXXwmA6EEJvxFcHTekvaEy0gG zrpLW3Dm1374eFKeRgiB+PvKc+1JjwP1UJAmYeJCiq+lvKK3hsZg6mQzoF99YxL0sWl/ xXsgpFdSgncVv6XCg+9LliAqmUTzn6hUycQ5mC+nCjzEiafs+demgHGAYTTA91L8rilI GlDw== X-Forwarded-Encrypted: i=1; AFNElJ/XVSRs8HLV2IDlVcx0GtNkBsq39l9x1ZWdCYmcAU38dJugRw5iuW7Wj4qml4mPzArNPAwqOqJb0Drkf68=@vger.kernel.org X-Gm-Message-State: AOJu0YxLfE69GIhtEr5R13+NtG7ilwtdc4MtpUPHB9EtRDSohL734nuk Rw4iPdfbohYEg5ZrBBVTcfjB5BQh6MVY79VYe5xJ16KHjIevZmDl6TKAok2CZbvZYHqJbkam5XU 1CCXO3NE= X-Gm-Gg: AfdE7ckF40Jqu0JSQ6pEABT6e5v8fZ8Zw6r9v30KukeWEgDKmYGbhO0pRIZsc9RJ7/K kn/SfRKN4jsKNinYluqLqnuUW/nbqVMfJvp8m+FAfumnN4c0DfWs+yk48TIwXjT29xKE285NOVX 0tixXzbx9ww3tNUXiylg06Cgy/cufW+n/ni/s/+p0mWBkQFQJQqcxZk/rAvsnsN4NQCQV+Cwqfy EWhvZEk4E+cy8w/QdpcLrSyeSrN9k99XN9+QgWU8vX8XRKkdkTLYWfCh9pxI7qjRNBZgq+uc08x rDcYbi0U0oheNIQcc9NNq93fuyrWjAGhtzlLUD8pKMPYtcA59c31QOPFCvNRqu1skU72/ztIthJ Yu4fgFQl+Xbm/RDkH0H7mzX1jn9Hj0FqYnnUkhH4laWRJ5cWEkITn3DkN/HI/Ya+MF4yFwEfZfI piv7271ca3SLJFUpRK9ElebszxHyeShcvI15k7Zqg= X-Received: by 2002:a05:6870:819d:b0:43c:3ae7:5e83 with SMTP id 586e51a60fabf-44690549596mr2920062fac.31.1781708058411; Wed, 17 Jun 2026 07:54:18 -0700 (PDT) Received: from [172.19.0.220] ([99.196.128.98]) by smtp.gmail.com with ESMTPSA id 586e51a60fabf-4430900e368sm4484893fac.16.2026.06.17.07.54.11 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Wed, 17 Jun 2026 07:54:17 -0700 (PDT) Message-ID: <2d35e4d2-72ec-4ae8-90ba-8c9b1e53c58f@kernel.dk> Date: Wed, 17 Jun 2026 08:54:04 -0600 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Subject: Re: [PATCH v2] [PATCH v2] io_uring/register: add IORING_REGISTER_CLONE_FILES opcode To: harshal24-chavan , kees@kernel.org Cc: gustavoars@kernel.org, io-uring@vger.kernel.org, linux-kernel@vger.kernel.org, linux-hardening@vger.kernel.org References: <20260617081622.32823-1-harshal24.chavan@gmail.com> Content-Language: en-US From: Jens Axboe In-Reply-To: <20260617081622.32823-1-harshal24.chavan@gmail.com> Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 7bit On 6/17/26 2:16 AM, harshal24-chavan wrote: > diff --git a/io_uring/rsrc.c b/io_uring/rsrc.c > index 650303626be6..1e4e114ca5a5 100644 > --- a/io_uring/rsrc.c > +++ b/io_uring/rsrc.c > @@ -1303,6 +1303,166 @@ int io_register_clone_buffers(struct io_ring_ctx *ctx, void __user *arg) > return ret; > } > > + > +static int io_clone_files(struct io_ring_ctx *ctx, struct io_ring_ctx *src_ctx, > + struct io_uring_clone_files *arg) > +{ > + struct io_file_table new_file_table; > + int i, off, nr; > + unsigned int src_nr; > + > + lockdep_assert_held(&ctx->uring_lock); > + lockdep_assert_held(&src_ctx->uring_lock); > + > + /* if offsets are given, must have nr specified too */ > + if (!arg->nr && (arg->dst_off || arg->src_off)) > + return -EINVAL; Not sure the offsets and partial copies are going to be worth it, but I'm willing to have my mind changed. But that's a minor thing really. > + /* not allowed unless REPLACE is set */ > + if (ctx->file_table.data.nr && > + !(arg->flags & IORING_REGISTER_DST_REPLACE)) > + return -EBUSY; > + > + src_nr = src_ctx->file_table.data.nr; > + if (!src_nr) > + return -ENXIO; > + if (!arg->nr) > + arg->nr = src_nr; > + else if (arg->nr > src_nr) > + return -EINVAL; > + else if (arg->nr > IORING_MAX_FIXED_FILES) > + return -EINVAL; > + if (check_add_overflow(arg->nr, arg->src_off, &off) || off > src_nr) > + return -EOVERFLOW; > + if (check_add_overflow(arg->nr, arg->dst_off, &src_nr)) > + return -EOVERFLOW; > + if (src_nr > IORING_MAX_FIXED_FILES) > + return -EINVAL; > + /* Allocate file tables memory {data + bitmap} into new_file_table */ > + memset(&new_file_table, 0, sizeof(new_file_table)); > + if (!io_alloc_file_tables(ctx, &new_file_table, > + max(src_nr, ctx->file_table.data.nr))) > + return -ENOMEM; Also a question whether the destination should've already allocated a sparse table. This kind of bundles the two into one. In general, as mention on the GH link, I do think this should work exactly like cloning buffers. It'd be somewhat confusing if they don't match up, as it's essentially the same operation, just on a different node type. > + /* Copy original dst nodes from before the cloned range */ > + for (i = 0; i < min(arg->dst_off, ctx->file_table.data.nr); i++) { > + struct io_rsrc_node *node = ctx->file_table.data.nodes[i]; > + > + if (node) { > + new_file_table.data.nodes[i] = node; > + node->refs++; > + io_file_bitmap_set(&new_file_table, i); > + } > + } This definitely won't work - I also mentioned in the GH link that nodes cannot be shared, you have to allocate new nodes on the destination side. > + while (nr--) { > + struct io_rsrc_node *dst_node, *src_node; > + > + src_node = io_rsrc_node_lookup(&src_ctx->file_table.data, i); > + if (!src_node) { > + dst_node = NULL; > + } else { > + dst_node = io_rsrc_node_alloc(ctx, IORING_RSRC_FILE); > + if (!dst_node) { > + io_free_file_tables(ctx, &new_file_table); > + return -ENOMEM; > + } > + > + struct file *file = io_slot_file(src_node); > + > + get_file(file); > + io_fixed_file_set(dst_node, file); > + } > + new_file_table.data.nodes[off] = dst_node; > + if (dst_node) > + io_file_bitmap_set(&new_file_table, off); > + > + i++; > + off++; > + } Same here, it needs a new node that's private to the destination. Hence you'd need to _always_ allocate one, assign the file, and get a reference to it. The file nodes rely on non-atomic refs when being used, which is protected by the ctx->uring_lock as that's always held for the fast path issue. If you just assign the node by reference, now you have two different rings manipulating the same node in memory, but they don't agree on synchronization. -- Jens Axboe