From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from shelob.surriel.com (shelob.surriel.com [96.67.55.147]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 78EE0C433EF for ; Tue, 1 Mar 2022 16:56:35 +0000 (UTC) Received: from localhost ([::1] helo=shelob.surriel.com) by shelob.surriel.com with esmtp (Exim 4.94.2) (envelope-from ) id 1nP5nO-0004WE-Rd; Tue, 01 Mar 2022 11:56:18 -0500 Received: from mail-4022.proton.ch ([185.70.40.22]) by shelob.surriel.com with esmtps (TLS1.2) tls TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1nP5nM-0004W5-Sg for kernelnewbies@kernelnewbies.org; Tue, 01 Mar 2022 11:56:17 -0500 Date: Tue, 01 Mar 2022 16:56:05 +0000 Authentication-Results: mail-4018.proton.ch; dkim=none To: kernelnewbies@kernelnewbies.org From: Torin Carey Subject: Re: Safe registration of procfs entries in LKM Message-ID: In-Reply-To: References: MIME-Version: 1.0 X-BeenThere: kernelnewbies@kernelnewbies.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: Learn about the Linux kernel List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: Torin Carey Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Errors-To: kernelnewbies-bounces@kernelnewbies.org Found answer from source so thought I'd share incase anyone else was interested: On Thu, Feb 24, 2022 at 02:12:57PM +0000, Torin Carey wrote: > The procfs code switched from `struct file_operations`, which has a > `struct module *owner` member to using `struct proc_ops`, which doesn't. > This member allowed the core code to `try_module_get()` the module > before calling the operation, so that we can avoid calling it if the > module is in the process of being removed and increase the module use > count to prevent the module from being unloaded while the open file > description exists. The procfs code doesn't modify module usage count, but it is still safe to use with removable modules for the following reason: The dereferencing of the proc file operations structures as well as their functions are guarded: // fs/proc/inode.c enum {BIAS = -1U<<31}; static inline int use_pde(struct proc_dir_entry *pde) { return likely(atomic_inc_unless_negative(&pde->in_use)); } static void unuse_pde(struct proc_dir_entry *pde) { if (unlikely(atomic_dec_return(&pde->in_use) == BIAS)) complete(pde->pde_unload_completion); } ... static ssize_t proc_reg_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) { struct proc_dir_entry *pde = PDE(file_inode(file)); ssize_t rv = -EIO; if (pde_is_permanent(pde)) { return pde_read(pde, file, buf, count, ppos); } else if (use_pde(pde)) { rv = pde_read(pde, file, buf, count, ppos); unuse_pde(pde); } return rv; } use_pde() will, if the pde isn't marked for removal (i.e. negative), increase the pde use count and return true. The actual module pde operations will be called through pde_read(), and the following unuse_pde() will decrease the pde use count afterwards. During pde removal, the pde use count will turn negative to BIAS (marking that it's being removed) and depending on whether the use count is still greater than BIAS (meaning it was previously positive), it will wait for the functions to return using a completion. When use_pde() detects that the pde is being removed, it will return false, which usually causes -EIO to be returned (or -ENOENT for open), avoiding calling the operations even for an open file description. If unuse_pde() detects that the pde is being removed, then it knows it's being waited on, so will complete the completion (if it's the last user of the pde). This, along with the open files automatically being ->release()'ed, make procfs safe for modules. Torin _______________________________________________ Kernelnewbies mailing list Kernelnewbies@kernelnewbies.org https://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies