Received: by 2002:a05:7412:8d10:b0:f3:1519:9f41 with SMTP id bj16csp5189327rdb; Wed, 13 Dec 2023 01:13:10 -0800 (PST) X-Google-Smtp-Source: AGHT+IGCm+7g0uzNFa7lbzzwIa7sHi2I8o15Cq6T+oQFRMEU7FCUDEtovv/lZsH6Z0FMOK8COn+r X-Received: by 2002:a05:6808:1902:b0:3b9:e566:d4db with SMTP id bf2-20020a056808190200b003b9e566d4dbmr11493182oib.78.1702458790683; Wed, 13 Dec 2023 01:13:10 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1702458790; cv=none; d=google.com; s=arc-20160816; b=Mm3Zi5kKDSli9gW/8b8sFCHpKthqKAZ6E2qv7y8flgrtH06ng0adR7KP80BQPJYXys YwEMWtezAm7CYP8n+kNiYoR8fweKlriXT7XZaN0mfEPTj9pLdc6FK+umY0KVGZ0s604u LzjIc5UUdJA+LM/2GrGVh4lbJ2cSRz5YG8iZZIn71FznNNjB5VIDrwQPVeFYxshjajAn YUjVhQl820EWGpijijofT1HLHJbiuZlSgTWTo6aRrppeg6ZRqAjNZAotiA3Q4Lslija6 da8Mg6kcK5MKni1lq2bLbw3hmOTJoBqq1nSZiDhY23dsgg1lGED44T3sMfzu6/Hf2R+Z FEHA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :feedback-id:references:in-reply-to:message-id:subject:cc:from:to :date:dkim-signature; bh=MEAwN2FYlBpSwYoH9a2PEuQpzLdTwET0cZNUdnLD5cQ=; fh=+lHGOCthbeAyoD/i5uiRAmL3p/+Aln9Z14w6lRldMQM=; b=ZAHHCtHIAFI827iOeX899PJa+5adqCt0Q/CePF8sM3C2x75cke+zk1xUFEmtQGoesN 951btTB8KT/fZkDG00vB12bgJF/BjzQPEPmRI5BOrqNmoIxyj2hIkOLXges2poWxpo4T 20Gb1yE04R3IX89TS+xMnrybtOUGnw/U7WJaHhYDx5D7RLyvr5gIWuUmcQ18NMadghcK Gz93m3MoVyDTiKP9rVazZ64mVt6m6ZWAjtwvK487xeRAgXW4c1DixQPVt4NPJu+RGnOb OU13rZAyzSp72YWa0JPxwg+B4CzsQF1/u09QpN/EspPDzfd3pZQdkbXZYBnes55NLYT6 B1tQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@proton.me header.s=protonmail header.b=TNE8211i; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.36 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=proton.me Return-Path: Received: from pete.vger.email (pete.vger.email. [23.128.96.36]) by mx.google.com with ESMTPS id z20-20020a056a001d9400b006cdfada31d0si9073911pfw.30.2023.12.13.01.13.10 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 13 Dec 2023 01:13:10 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.36 as permitted sender) client-ip=23.128.96.36; Authentication-Results: mx.google.com; dkim=pass header.i=@proton.me header.s=protonmail header.b=TNE8211i; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.36 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=proton.me Received: from out1.vger.email (depot.vger.email [IPv6:2620:137:e000::3:0]) by pete.vger.email (Postfix) with ESMTP id D1BB58145540; Wed, 13 Dec 2023 01:13:07 -0800 (PST) X-Virus-Status: Clean X-Virus-Scanned: clamav-milter 0.103.11 at pete.vger.email Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231664AbjLMJMx (ORCPT + 99 others); Wed, 13 Dec 2023 04:12:53 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:52214 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229458AbjLMJMx (ORCPT ); Wed, 13 Dec 2023 04:12:53 -0500 Received: from mail-4322.protonmail.ch (mail-4322.protonmail.ch [185.70.43.22]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 0104BAD; Wed, 13 Dec 2023 01:12:55 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=proton.me; s=protonmail; t=1702458773; x=1702717973; bh=MEAwN2FYlBpSwYoH9a2PEuQpzLdTwET0cZNUdnLD5cQ=; h=Date:To:From:Cc:Subject:Message-ID:In-Reply-To:References: Feedback-ID:From:To:Cc:Date:Subject:Reply-To:Feedback-ID: Message-ID:BIMI-Selector; b=TNE8211i36nwjpY1JK6pg5ubksVz22Xteuzh7eG3Dx6D16cLt/98MFjBnFFh0TYDI u88OAAePGhRGa1h2qs7ZKQT72O/Psf9cAk/QNwVGPO1Kx/6qw4FYvta40OW/JXdijc IPFVOXjaJO1vn9+28PLVCW4oMrgQAh4kiNIjKNgIBkL9kQUPb0b7IMukn1nRU3zxE9 NjMx1ToEuUf5AoW56NP9I8bh8QZ1CM2Ti7r4cKaFC1dYWPzF+/OTaQtGMAhDh8FPWZ 0pkNK965rJf6+yPB2kv7avltEGgYoMJQzna+9Fc/i8GGszfqGnjoe969P9ZBNyPKJ9 XatbtEdnyTAig== Date: Wed, 13 Dec 2023 09:12:45 +0000 To: Boqun Feng From: Benno Lossin Cc: Alice Ryhl , Miguel Ojeda , Alex Gaynor , Wedson Almeida Filho , Gary Guo , =?utf-8?Q?Bj=C3=B6rn_Roy_Baron?= , Andreas Hindborg , Peter Zijlstra , Alexander Viro , Christian Brauner , Greg Kroah-Hartman , =?utf-8?Q?Arve_Hj=C3=B8nnev=C3=A5g?= , Todd Kjos , Martijn Coenen , Joel Fernandes , Carlos Llamas , Suren Baghdasaryan , Dan Williams , Kees Cook , Matthew Wilcox , Thomas Gleixner , Daniel Xu , linux-kernel@vger.kernel.org, rust-for-linux@vger.kernel.org, linux-fsdevel@vger.kernel.org Subject: Re: [PATCH v2 7/7] rust: file: add abstraction for `poll_table` Message-ID: In-Reply-To: References: <20231206-alice-file-v2-0-af617c0d9d94@google.com> <20231206-alice-file-v2-7-af617c0d9d94@google.com> Feedback-ID: 71780778:user:proton MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable X-Spam-Status: No, score=-0.9 required=5.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI, SPF_HELO_NONE,SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on pete.vger.email Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-Greylist: Sender passed SPF test, not delayed by milter-greylist-4.6.4 (pete.vger.email [0.0.0.0]); Wed, 13 Dec 2023 01:13:08 -0800 (PST) On 12/13/23 02:35, Boqun Feng wrote: > On Tue, Dec 12, 2023 at 05:01:28PM +0000, Benno Lossin wrote: >> On 12/12/23 10:59, Alice Ryhl wrote: >>> On Fri, Dec 8, 2023 at 6:53=E2=80=AFPM Benno Lossin wrote: >>>> On 12/6/23 12:59, Alice Ryhl wrote: >>>>> + fn get_qproc(&self) -> bindings::poll_queue_proc { >>>>> + let ptr =3D self.0.get(); >>>>> + // SAFETY: The `ptr` is valid because it originates from a r= eference, and the `_qproc` >>>>> + // field is not modified concurrently with this call since w= e have an immutable reference. >>>> >>>> This needs an invariant on `PollTable` (i.e. `self.0` is valid). >>> >>> How would you phrase it? >> >> - `self.0` contains a valid `bindings::poll_table`. >> - `self.0` is only modified via references to `Self`. >> >>>>> + unsafe { (*ptr)._qproc } >>>>> + } >>>>> + >>>>> + /// Register this [`PollTable`] with the provided [`PollCondVar`= ], so that it can be notified >>>>> + /// using the condition variable. >>>>> + pub fn register_wait(&mut self, file: &File, cv: &PollCondVar) { >>>>> + if let Some(qproc) =3D self.get_qproc() { >>>>> + // SAFETY: The pointers to `self` and `file` are valid b= ecause they are references. >>>> >>>> What about cv.wait_list... >>> >>> I can add it to the list of things that are valid due to references. >> >=20 > Actually, there is an implied safety requirement here, it's about how > qproc is implemented. As we can see, PollCondVar::drop() will wait for a > RCU grace period, that means the waiter (a file or something) has to use > RCU to access the cv.wait_list, otherwise, the synchronize_rcu() in > PollCondVar::drop() won't help. Good catch, this is rather important. I did not find the implementation of `qproc`, since it is a function pointer. Since this pattern is common, what is the way to find the implementation of those in general? I imagine that the pattern is used to enable dynamic selection of the concrete implementation, but there must be some general specification of what the function does, is this documented somewhere? > To phrase it, it's more like: >=20 > (in the safety requirement of `PollTable::from_ptr` and the type > invariant of `PollTable`): >=20 > ", further, if the qproc function in poll_table publishs the pointer of > the wait_queue_head, it must publish it in a way that reads on the > published pointer have to be in an RCU read-side critical section." What do you mean by `publish`? > and here we can said, >=20 > "per type invariant, `qproc` cannot publish `cv.wait_list` without > proper RCU protection, so it's safe to use `cv.wait_list` here, and with > the synchronize_rcu() in PollCondVar::drop(), free of the wait_list will > be delayed until all usages are done." I think I am missing how the call to `__wake_up_pollfree` ensures that nobody uses the `PollCondVar` any longer. How is it removed from the table? --=20 Cheers, Benno > I know, this is quite verbose, but just imagine some one removes the > rcu_read_lock() and rcu_read_unlock() in ep_remove_wait_queue(), the > poll table from epoll (using ep_ptable_queue_proc()) is still valid one > according to the current safety requirement, but now there is a > use-after-free in the following case: >=20 > =09CPU 0 CPU1 > =09 ep_remove_wait_queue(): > =09=09=09=09 struct wait_queue_head *whead; > =09 whead =3D smp_load_acquire(...); > =09 if (whead) { // not null > =09PollCondVar::drop(): > =09 __wake_pollfree(); > =09 synchronize_rcu(); // no current RCU readers, yay. > =09 > =09 remove_wait_queue(whead, ...); // BOO= M, use-after-free