From patchwork Tue Dec 10 17:02:19 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: James Bottomley X-Patchwork-Id: 850548 Received: from bedivere.hansenpartnership.com (bedivere.hansenpartnership.com [96.44.175.130]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 0AD162063FB; Tue, 10 Dec 2024 17:02:57 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=96.44.175.130 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1733850179; cv=none; b=fOtOudOoOLDfsnc/IqnbOzQHGemBGe7nAQuFW9m0mmNN6I9yrdoauwjciWpqDYP3gJaYaTVYWBd+QpARz+kXcNernzj99jHBTj4JtOol5h46VoLQ5ClXXCl/aLECLOKOZb6b421rh+WhF4FEtuGlNBLVLgl8uf9Q5Ry2137ebxE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1733850179; c=relaxed/simple; bh=vgO2sbLgqWuxG0mPPsC+kAavuiDQGRuD9LU5zv4R5ec=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=p5EsIzvZ0ZWQTpaRiJuO6qpvqJ1ZCtAx4Icvdo6jRjjxZ/slScykplazWBwsqOS45ZPxoaK1mXSYWF3qxr1u6q0H8LvxI7Yi0gonmDOBsK/mCa+OfR9TI1Sa0iUkABz7wlEvH58vh43NGHEVr0wm841iJZAtHhuontMX8U4omo8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=HansenPartnership.com; spf=pass smtp.mailfrom=HansenPartnership.com; dkim=pass (1024-bit key) header.d=hansenpartnership.com header.i=@hansenpartnership.com header.b=OxmozZcT; arc=none smtp.client-ip=96.44.175.130 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=HansenPartnership.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=HansenPartnership.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=hansenpartnership.com header.i=@hansenpartnership.com header.b="OxmozZcT" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=hansenpartnership.com; s=20151216; t=1733850177; bh=vgO2sbLgqWuxG0mPPsC+kAavuiDQGRuD9LU5zv4R5ec=; h=From:To:Subject:Date:Message-Id:In-Reply-To:References:From; b=OxmozZcTuKch6BglcBklhfcLUd3KH+yoLrzouyitmQdWGNozEfCrm6o0cf9c5TkCV 8zdG4hy9I/cdyVGymkMOQ9EAFaa8NiJqR5xOKv1oIz0T71b53Ak71beuDQhXaqgb/G lHeTQP0vX8wUl8+gC8NWu2aYHPE7D+TxLvsJto6U= Received: from localhost (localhost [127.0.0.1]) by bedivere.hansenpartnership.com (Postfix) with ESMTP id 3CD9612813BB; Tue, 10 Dec 2024 12:02:57 -0500 (EST) Received: from bedivere.hansenpartnership.com ([127.0.0.1]) by localhost (bedivere.hansenpartnership.com [127.0.0.1]) (amavis, port 10024) with ESMTP id pWP26BmmNXYt; Tue, 10 Dec 2024 12:02:57 -0500 (EST) Received: from lingrow.int.hansenpartnership.com (unknown [153.66.160.227]) by bedivere.hansenpartnership.com (Postfix) with ESMTP id AC32E12813B6; Tue, 10 Dec 2024 12:02:56 -0500 (EST) From: James Bottomley To: linux-fsdevel@vger.kernel.org, linux-efi@vger.kernel.org Cc: Ard Biesheuvel , Jeremy Kerr Subject: [PATCH 1/6] efivarfs: remove unused efi_varaible.Attributes and .kobj Date: Tue, 10 Dec 2024 12:02:19 -0500 Message-Id: <20241210170224.19159-2-James.Bottomley@HansenPartnership.com> X-Mailer: git-send-email 2.35.3 In-Reply-To: <20241210170224.19159-1-James.Bottomley@HansenPartnership.com> References: <20241210170224.19159-1-James.Bottomley@HansenPartnership.com> Precedence: bulk X-Mailing-List: linux-efi@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 These fields look to be remnants of older code: Attributes was likely meant to stash the variable attributes, but doesn't because we always read them from the variable store and kobj was likely left over from an older iteration of code where we manually created the objects instead of using a filesystem. Signed-off-by: James Bottomley --- fs/efivarfs/internal.h | 2 -- fs/efivarfs/super.c | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/fs/efivarfs/internal.h b/fs/efivarfs/internal.h index d71d2e08422f..107aad8a3443 100644 --- a/fs/efivarfs/internal.h +++ b/fs/efivarfs/internal.h @@ -24,13 +24,11 @@ struct efivarfs_fs_info { struct efi_variable { efi_char16_t VariableName[EFI_VAR_NAME_LEN/sizeof(efi_char16_t)]; efi_guid_t VendorGuid; - __u32 Attributes; }; struct efivar_entry { struct efi_variable var; struct list_head list; - struct kobject kobj; }; int efivar_init(int (*func)(efi_char16_t *, efi_guid_t, unsigned long, void *, diff --git a/fs/efivarfs/super.c b/fs/efivarfs/super.c index beba15673be8..d3c8528274aa 100644 --- a/fs/efivarfs/super.c +++ b/fs/efivarfs/super.c @@ -245,7 +245,7 @@ static int efivarfs_callback(efi_char16_t *name16, efi_guid_t vendor, inode_lock(inode); inode->i_private = entry; - i_size_write(inode, size + sizeof(entry->var.Attributes)); + i_size_write(inode, size + sizeof(__u32)); /* attributes + data */ inode_unlock(inode); d_add(dentry, inode); From patchwork Tue Dec 10 17:02:20 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: James Bottomley X-Patchwork-Id: 848944 Received: from bedivere.hansenpartnership.com (bedivere.hansenpartnership.com [96.44.175.130]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E993D2063FB; Tue, 10 Dec 2024 17:03:10 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=96.44.175.130 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1733850192; cv=none; b=puawpO8Ei7SBqfbB67oIVehqaExU0R/+DF5znhsMsuLNf7u/9qtDxRtUN0X2peocHxeHcMtmG+RKanFTP8JrBN6UN/nqpSN7OtMQJ27UWe5LNqB7Uc+f1fN2JvBkVdX/fWwuqQIdj8KFd4qpNNg+P/JhpHUoQuHW+uyJWr1Sqb0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1733850192; c=relaxed/simple; bh=HENCyC5/taTHHYRATRKhoQp0ZDr7E3TIdvECCrUe3gA=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=E4+iI02f2+K62ErKkkofTSAiiuiCdACbguIYfroRtefH7fvKne7KENS26XrWFrH2sfKFvu8pOOHYISpGQ9reSEopNRrWA5BGF4YxD6arG4f7iZC5AjFfQCRPmIN8HQn6zljMbLTKsaycukQXdmgYugJN1DqfuWKZ/cU68LTDxHI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=HansenPartnership.com; spf=pass smtp.mailfrom=HansenPartnership.com; dkim=pass (1024-bit key) header.d=hansenpartnership.com header.i=@hansenpartnership.com header.b=ablJwlJU; arc=none smtp.client-ip=96.44.175.130 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=HansenPartnership.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=HansenPartnership.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=hansenpartnership.com header.i=@hansenpartnership.com header.b="ablJwlJU" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=hansenpartnership.com; s=20151216; t=1733850190; bh=HENCyC5/taTHHYRATRKhoQp0ZDr7E3TIdvECCrUe3gA=; h=From:To:Subject:Date:Message-Id:In-Reply-To:References:From; b=ablJwlJUYIYQ7yh8GBEKzPKRpmaxDHwNwrWaxswKYvaqCyDJpeBLkmdSS80j5pkGH ye0boXin/VebjYFJMMFxa4qR9WRG/jbaAWrc1KUNvjdYkT6tmwZ75GyKzkMpbdWtN6 GIm8eKB8lGICR7RjDOkxYHPLK0Yw8lTIgko/bhyE= Received: from localhost (localhost [127.0.0.1]) by bedivere.hansenpartnership.com (Postfix) with ESMTP id 4FE6A12813BB; Tue, 10 Dec 2024 12:03:10 -0500 (EST) Received: from bedivere.hansenpartnership.com ([127.0.0.1]) by localhost (bedivere.hansenpartnership.com [127.0.0.1]) (amavis, port 10024) with ESMTP id C5H9FtMGbGvR; Tue, 10 Dec 2024 12:03:10 -0500 (EST) Received: from lingrow.int.hansenpartnership.com (unknown [153.66.160.227]) by bedivere.hansenpartnership.com (Postfix) with ESMTP id A3B5212813B6; Tue, 10 Dec 2024 12:03:09 -0500 (EST) From: James Bottomley To: linux-fsdevel@vger.kernel.org, linux-efi@vger.kernel.org Cc: Ard Biesheuvel , Jeremy Kerr Subject: [PATCH 2/6] efivarfs: add helper to convert from UC16 name and GUID to utf8 name Date: Tue, 10 Dec 2024 12:02:20 -0500 Message-Id: <20241210170224.19159-3-James.Bottomley@HansenPartnership.com> X-Mailer: git-send-email 2.35.3 In-Reply-To: <20241210170224.19159-1-James.Bottomley@HansenPartnership.com> References: <20241210170224.19159-1-James.Bottomley@HansenPartnership.com> Precedence: bulk X-Mailing-List: linux-efi@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 These will be used by a later patch to check for uniqueness on initial EFI variable iteration. Signed-off-by: James Bottomley --- fs/efivarfs/internal.h | 1 + fs/efivarfs/super.c | 17 +++-------------- fs/efivarfs/vars.c | 25 +++++++++++++++++++++++++ 3 files changed, 29 insertions(+), 14 deletions(-) diff --git a/fs/efivarfs/internal.h b/fs/efivarfs/internal.h index 107aad8a3443..4b7330b90958 100644 --- a/fs/efivarfs/internal.h +++ b/fs/efivarfs/internal.h @@ -55,6 +55,7 @@ bool efivar_validate(efi_guid_t vendor, efi_char16_t *var_name, u8 *data, unsigned long data_size); bool efivar_variable_is_removable(efi_guid_t vendor, const char *name, size_t len); +char *efivar_get_utf8name(const efi_char16_t *name16, efi_guid_t *vendor); extern const struct file_operations efivarfs_file_operations; extern const struct inode_operations efivarfs_dir_inode_operations; diff --git a/fs/efivarfs/super.c b/fs/efivarfs/super.c index d3c8528274aa..b22441f7f7c6 100644 --- a/fs/efivarfs/super.c +++ b/fs/efivarfs/super.c @@ -205,27 +205,16 @@ static int efivarfs_callback(efi_char16_t *name16, efi_guid_t vendor, memcpy(entry->var.VariableName, name16, name_size); memcpy(&(entry->var.VendorGuid), &vendor, sizeof(efi_guid_t)); - len = ucs2_utf8size(entry->var.VariableName); - - /* name, plus '-', plus GUID, plus NUL*/ - name = kmalloc(len + 1 + EFI_VARIABLE_GUID_LEN + 1, GFP_KERNEL); + name = efivar_get_utf8name(name16, &vendor); if (!name) goto fail; - ucs2_as_utf8(name, entry->var.VariableName, len); + /* length of the variable name itself: remove GUID and separator */ + len = strlen(name) - EFI_VARIABLE_GUID_LEN - 1; if (efivar_variable_is_removable(entry->var.VendorGuid, name, len)) is_removable = true; - name[len] = '-'; - - efi_guid_to_str(&entry->var.VendorGuid, name + len + 1); - - name[len + EFI_VARIABLE_GUID_LEN+1] = '\0'; - - /* replace invalid slashes like kobject_set_name_vargs does for /sys/firmware/efi/vars. */ - strreplace(name, '/', '!'); - inode = efivarfs_get_inode(sb, d_inode(root), S_IFREG | 0644, 0, is_removable); if (!inode) diff --git a/fs/efivarfs/vars.c b/fs/efivarfs/vars.c index 3cc89bb624f0..7a07b767e2cc 100644 --- a/fs/efivarfs/vars.c +++ b/fs/efivarfs/vars.c @@ -225,6 +225,31 @@ variable_matches(const char *var_name, size_t len, const char *match_name, } } +char * +efivar_get_utf8name(const efi_char16_t *name16, efi_guid_t *vendor) +{ + int len = ucs2_utf8size(name16); + char *name; + + /* name, plus '-', plus GUID, plus NUL*/ + name = kmalloc(len + 1 + EFI_VARIABLE_GUID_LEN + 1, GFP_KERNEL); + if (!name) + return NULL; + + ucs2_as_utf8(name, name16, len); + + name[len] = '-'; + + efi_guid_to_str(vendor, name + len + 1); + + name[len + EFI_VARIABLE_GUID_LEN+1] = '\0'; + + /* replace invalid slashes like kobject_set_name_vargs does for /sys/firmware/efi/vars. */ + strreplace(name, '/', '!'); + + return name; +} + bool efivar_validate(efi_guid_t vendor, efi_char16_t *var_name, u8 *data, unsigned long data_size) From patchwork Tue Dec 10 17:02:21 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: James Bottomley X-Patchwork-Id: 850547 Received: from bedivere.hansenpartnership.com (bedivere.hansenpartnership.com [96.44.175.130]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 5FDAD231C8E; Tue, 10 Dec 2024 17:03:28 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=96.44.175.130 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1733850209; cv=none; b=L9V0K/VZUxhr25ztviHcBfe5MynujE+DcdJi9lFgPrBqdWnW9Uttob4X1qTR2v7GS8J9Pau5lwbZdQ+G7BQpdkhxFIsTpcRBQ+8mzyNKcWggqGeQwqd3i2zSx7bEXq5L7eKNwOLuuqVS+2QOFf0e+VoZ4CVNhaX68NCWoLQjn00= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1733850209; c=relaxed/simple; bh=6Mp50iC3bNfaQ0SjKfrVdZcmz5QNH6PyRbjXsJphRwU=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=NjO++rC/6BnDUK1KGZfzNTUfjO3iuVFRvIWgUjQYCDG9XTJw+hqY2yGns4ACxM2RCtjSznoQkRB1FQeHfm/AtE6Exn4KgoGOElEvZrMi1A1DG3VEiXzUbg0j/q1psb6zWwegzGQ6X2Tz3DLKhmbHFbZ10zGzQHuDg0SOToMllPw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=HansenPartnership.com; spf=pass smtp.mailfrom=HansenPartnership.com; dkim=pass (1024-bit key) header.d=hansenpartnership.com header.i=@hansenpartnership.com header.b=D58/tVJO; arc=none smtp.client-ip=96.44.175.130 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=HansenPartnership.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=HansenPartnership.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=hansenpartnership.com header.i=@hansenpartnership.com header.b="D58/tVJO" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=hansenpartnership.com; s=20151216; t=1733850207; bh=6Mp50iC3bNfaQ0SjKfrVdZcmz5QNH6PyRbjXsJphRwU=; h=From:To:Subject:Date:Message-Id:In-Reply-To:References:From; b=D58/tVJOGAOkKCfrcyFr6oSxJvsVgGeC7KAemy5+Gkrk989/1EFhtLcNeIP9KLibu O8mWxZeDj72zcfHeniwDY/oZdzyBHAr3FqdMMos/GHjcH2UZb5q9mUHIxUAgtt04fQ 3T2i5As0s8+AfAkzLZx3kYiAMUcsQY2cfUEyBiH4= Received: from localhost (localhost [127.0.0.1]) by bedivere.hansenpartnership.com (Postfix) with ESMTP id 92AE812813BB; Tue, 10 Dec 2024 12:03:27 -0500 (EST) Received: from bedivere.hansenpartnership.com ([127.0.0.1]) by localhost (bedivere.hansenpartnership.com [127.0.0.1]) (amavis, port 10024) with ESMTP id gKanO3gje6ad; Tue, 10 Dec 2024 12:03:27 -0500 (EST) Received: from lingrow.int.hansenpartnership.com (unknown [153.66.160.227]) by bedivere.hansenpartnership.com (Postfix) with ESMTP id C96C312813B6; Tue, 10 Dec 2024 12:03:26 -0500 (EST) From: James Bottomley To: linux-fsdevel@vger.kernel.org, linux-efi@vger.kernel.org Cc: Ard Biesheuvel , Jeremy Kerr Subject: [PATCH 3/6] efivarfs: make variable_is_present use dcache lookup Date: Tue, 10 Dec 2024 12:02:21 -0500 Message-Id: <20241210170224.19159-4-James.Bottomley@HansenPartnership.com> X-Mailer: git-send-email 2.35.3 In-Reply-To: <20241210170224.19159-1-James.Bottomley@HansenPartnership.com> References: <20241210170224.19159-1-James.Bottomley@HansenPartnership.com> Precedence: bulk X-Mailing-List: linux-efi@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Instead of searching the variable entry list for a variable, use the dcache lookup functions to find it instead. Also add an efivarfs_ prefix to the function now it is no longer static. Signed-off-by: James Bottomley --- fs/efivarfs/internal.h | 4 ++++ fs/efivarfs/super.c | 20 ++++++++++++++++++++ fs/efivarfs/vars.c | 26 ++------------------------ 3 files changed, 26 insertions(+), 24 deletions(-) diff --git a/fs/efivarfs/internal.h b/fs/efivarfs/internal.h index 4b7330b90958..84a36e6fb653 100644 --- a/fs/efivarfs/internal.h +++ b/fs/efivarfs/internal.h @@ -56,6 +56,8 @@ bool efivar_validate(efi_guid_t vendor, efi_char16_t *var_name, u8 *data, bool efivar_variable_is_removable(efi_guid_t vendor, const char *name, size_t len); char *efivar_get_utf8name(const efi_char16_t *name16, efi_guid_t *vendor); +bool efivarfs_variable_is_present(efi_char16_t *variable_name, + efi_guid_t *vendor, void *data); extern const struct file_operations efivarfs_file_operations; extern const struct inode_operations efivarfs_dir_inode_operations; @@ -64,4 +66,6 @@ extern struct inode *efivarfs_get_inode(struct super_block *sb, const struct inode *dir, int mode, dev_t dev, bool is_removable); + + #endif /* EFIVAR_FS_INTERNAL_H */ diff --git a/fs/efivarfs/super.c b/fs/efivarfs/super.c index b22441f7f7c6..dc3870ae784b 100644 --- a/fs/efivarfs/super.c +++ b/fs/efivarfs/super.c @@ -181,6 +181,26 @@ static struct dentry *efivarfs_alloc_dentry(struct dentry *parent, char *name) return ERR_PTR(-ENOMEM); } +bool efivarfs_variable_is_present(efi_char16_t *variable_name, + efi_guid_t *vendor, void *data) +{ + char *name = efivar_get_utf8name(variable_name, vendor); + struct super_block *sb = data; + struct dentry *dentry; + struct qstr qstr; + + if (!name) + return true; + + qstr.name = name; + qstr.len = strlen(name); + dentry = d_hash_and_lookup(sb->s_root, &qstr); + kfree(name); + if (dentry) + dput(dentry); + return dentry != NULL; +} + static int efivarfs_callback(efi_char16_t *name16, efi_guid_t vendor, unsigned long name_size, void *data, struct list_head *list) diff --git a/fs/efivarfs/vars.c b/fs/efivarfs/vars.c index 7a07b767e2cc..f6380fdbe173 100644 --- a/fs/efivarfs/vars.c +++ b/fs/efivarfs/vars.c @@ -313,28 +313,6 @@ efivar_variable_is_removable(efi_guid_t vendor, const char *var_name, return found; } -static bool variable_is_present(efi_char16_t *variable_name, efi_guid_t *vendor, - struct list_head *head) -{ - struct efivar_entry *entry, *n; - unsigned long strsize1, strsize2; - bool found = false; - - strsize1 = ucs2_strsize(variable_name, EFI_VAR_NAME_LEN); - list_for_each_entry_safe(entry, n, head, list) { - strsize2 = ucs2_strsize(entry->var.VariableName, EFI_VAR_NAME_LEN); - if (strsize1 == strsize2 && - !memcmp(variable_name, &(entry->var.VariableName), - strsize2) && - !efi_guidcmp(entry->var.VendorGuid, - *vendor)) { - found = true; - break; - } - } - return found; -} - /* * Returns the size of variable_name, in bytes, including the * terminating NULL character, or variable_name_size if no NULL @@ -439,8 +417,8 @@ int efivar_init(int (*func)(efi_char16_t *, efi_guid_t, unsigned long, void *, * we'll ever see a different variable name, * and may end up looping here forever. */ - if (variable_is_present(variable_name, &vendor_guid, - head)) { + if (efivarfs_variable_is_present(variable_name, + &vendor_guid, data)) { dup_variable_bug(variable_name, &vendor_guid, variable_name_size); status = EFI_NOT_FOUND; From patchwork Tue Dec 10 17:02:22 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: James Bottomley X-Patchwork-Id: 848943 Received: from bedivere.hansenpartnership.com (bedivere.hansenpartnership.com [96.44.175.130]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A72792327A9; Tue, 10 Dec 2024 17:03:45 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=96.44.175.130 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1733850227; cv=none; b=R9JWgqEP5k2nH6n5rZuOPGXq1wA9P1nG3OxTgfZFLVeAMsdzlireACPoFLvi82L/IJp+sTDxZQd345gEP1fvh+gZLST1/VfB03FO6ZuE32Vw1EgGOcWxHmJF6RSrdd8T9NfD8yqnOxv5ke6YZ+CNVe2echUpB4o+lczsCqtLZy4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1733850227; c=relaxed/simple; bh=XMUxmN/lKFGxcD+y+4IND8ySLKRc9nUNBYc6o60jlqQ=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=e7b3MSShwOwiHyWMmvB6UWvQ61/PVuLeOkvZUQ/v7fNcbfPZBmrqxF6+X7FAi4M9yXa4qI+Dv+K7P6+U38EyvGpD0TAS58BoVnFDXwKBqZ8M43RXdjEcn/RGsS3ET4254jZiJ5zAoTzcH2HZLO74f3CjZmzSthKd3f0G///KJek= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=HansenPartnership.com; spf=pass smtp.mailfrom=HansenPartnership.com; dkim=pass (1024-bit key) header.d=hansenpartnership.com header.i=@hansenpartnership.com header.b=Lopd55rM; arc=none smtp.client-ip=96.44.175.130 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=HansenPartnership.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=HansenPartnership.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=hansenpartnership.com header.i=@hansenpartnership.com header.b="Lopd55rM" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=hansenpartnership.com; s=20151216; t=1733850225; bh=XMUxmN/lKFGxcD+y+4IND8ySLKRc9nUNBYc6o60jlqQ=; h=From:To:Subject:Date:Message-Id:In-Reply-To:References:From; b=Lopd55rMq1j+t2kma0FPBDFYUN9fMUuU7RCvj5nIMadPrhQLk2I8kE8pOV1FrZf// poIfCE1Bd84VcJpPTadTgmxFjdmCw/YEvfXmYv/sqCqmfdXzZpFnjITtOSGmpdH69r wWOsSxmTjDKctiqKVhXbyl7SVjGLXLlKz4LAy+Uk= Received: from localhost (localhost [127.0.0.1]) by bedivere.hansenpartnership.com (Postfix) with ESMTP id 1177912813BB; Tue, 10 Dec 2024 12:03:45 -0500 (EST) Received: from bedivere.hansenpartnership.com ([127.0.0.1]) by localhost (bedivere.hansenpartnership.com [127.0.0.1]) (amavis, port 10024) with ESMTP id kjHLy__HkyvD; Tue, 10 Dec 2024 12:03:44 -0500 (EST) Received: from lingrow.int.hansenpartnership.com (unknown [153.66.160.227]) by bedivere.hansenpartnership.com (Postfix) with ESMTP id 7039412813B6; Tue, 10 Dec 2024 12:03:44 -0500 (EST) From: James Bottomley To: linux-fsdevel@vger.kernel.org, linux-efi@vger.kernel.org Cc: Ard Biesheuvel , Jeremy Kerr Subject: [PATCH 4/6] efivarfs: move freeing of variable entry into evict_inode Date: Tue, 10 Dec 2024 12:02:22 -0500 Message-Id: <20241210170224.19159-5-James.Bottomley@HansenPartnership.com> X-Mailer: git-send-email 2.35.3 In-Reply-To: <20241210170224.19159-1-James.Bottomley@HansenPartnership.com> References: <20241210170224.19159-1-James.Bottomley@HansenPartnership.com> Precedence: bulk X-Mailing-List: linux-efi@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Make the inodes the default management vehicle for struct efivar_entry, so they are now all freed automatically if the file is removed and on unmount in kill_litter_super(). Remove the now superfluous iterator to free the entries after kill_litter_super(). Also fixes a bug where some entry freeing was missing causing efivarfs to leak memory. Signed-off-by: James Bottomley --- fs/efivarfs/internal.h | 1 - fs/efivarfs/super.c | 15 +++++++-------- fs/efivarfs/vars.c | 39 +++------------------------------------ 3 files changed, 10 insertions(+), 45 deletions(-) diff --git a/fs/efivarfs/internal.h b/fs/efivarfs/internal.h index 84a36e6fb653..d768bfa7f12b 100644 --- a/fs/efivarfs/internal.h +++ b/fs/efivarfs/internal.h @@ -37,7 +37,6 @@ int efivar_init(int (*func)(efi_char16_t *, efi_guid_t, unsigned long, void *, int efivar_entry_add(struct efivar_entry *entry, struct list_head *head); void __efivar_entry_add(struct efivar_entry *entry, struct list_head *head); -void efivar_entry_remove(struct efivar_entry *entry); int efivar_entry_delete(struct efivar_entry *entry); int efivar_entry_size(struct efivar_entry *entry, unsigned long *size); diff --git a/fs/efivarfs/super.c b/fs/efivarfs/super.c index dc3870ae784b..70b99f58c906 100644 --- a/fs/efivarfs/super.c +++ b/fs/efivarfs/super.c @@ -41,6 +41,12 @@ static int efivarfs_ops_notifier(struct notifier_block *nb, unsigned long event, static void efivarfs_evict_inode(struct inode *inode) { + struct efivar_entry *entry = inode->i_private; + + if (entry) { + list_del(&entry->list); + kfree(entry); + } clear_inode(inode); } @@ -269,13 +275,6 @@ static int efivarfs_callback(efi_char16_t *name16, efi_guid_t vendor, return err; } -static int efivarfs_destroy(struct efivar_entry *entry, void *data) -{ - efivar_entry_remove(entry); - kfree(entry); - return 0; -} - enum { Opt_uid, Opt_gid, }; @@ -398,7 +397,7 @@ static void efivarfs_kill_sb(struct super_block *sb) kill_litter_super(sb); /* Remove all entries and destroy */ - efivar_entry_iter(efivarfs_destroy, &sfi->efivarfs_list, NULL); + WARN_ON(!list_empty(&sfi->efivarfs_list)); kfree(sfi); } diff --git a/fs/efivarfs/vars.c b/fs/efivarfs/vars.c index f6380fdbe173..bda8e8b869e8 100644 --- a/fs/efivarfs/vars.c +++ b/fs/efivarfs/vars.c @@ -485,34 +485,6 @@ void __efivar_entry_add(struct efivar_entry *entry, struct list_head *head) list_add(&entry->list, head); } -/** - * efivar_entry_remove - remove entry from variable list - * @entry: entry to remove from list - * - * Returns 0 on success, or a kernel error code on failure. - */ -void efivar_entry_remove(struct efivar_entry *entry) -{ - list_del(&entry->list); -} - -/* - * efivar_entry_list_del_unlock - remove entry from variable list - * @entry: entry to remove - * - * Remove @entry from the variable list and release the list lock. - * - * NOTE: slightly weird locking semantics here - we expect to be - * called with the efivars lock already held, and we release it before - * returning. This is because this function is usually called after - * set_variable() while the lock is still held. - */ -static void efivar_entry_list_del_unlock(struct efivar_entry *entry) -{ - list_del(&entry->list); - efivar_unlock(); -} - /** * efivar_entry_delete - delete variable and remove entry from list * @entry: entry containing variable to delete @@ -536,12 +508,10 @@ int efivar_entry_delete(struct efivar_entry *entry) status = efivar_set_variable_locked(entry->var.VariableName, &entry->var.VendorGuid, 0, 0, NULL, false); - if (!(status == EFI_SUCCESS || status == EFI_NOT_FOUND)) { - efivar_unlock(); + efivar_unlock(); + if (!(status == EFI_SUCCESS || status == EFI_NOT_FOUND)) return efi_status_to_err(status); - } - efivar_entry_list_del_unlock(entry); return 0; } @@ -679,10 +649,7 @@ int efivar_entry_set_get_size(struct efivar_entry *entry, u32 attributes, &entry->var.VendorGuid, NULL, size, NULL); - if (status == EFI_NOT_FOUND) - efivar_entry_list_del_unlock(entry); - else - efivar_unlock(); + efivar_unlock(); if (status && status != EFI_BUFFER_TOO_SMALL) return efi_status_to_err(status); From patchwork Tue Dec 10 17:02:23 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: James Bottomley X-Patchwork-Id: 850546 Received: from bedivere.hansenpartnership.com (bedivere.hansenpartnership.com [96.44.175.130]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 341161BC09F; Tue, 10 Dec 2024 17:03:58 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=96.44.175.130 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1733850240; cv=none; b=Te8aJrbo8ylFs7VhstQcWCyVKaVGDK/lUYZCWgWJUep1rqWeVRVxyec2IycHyg53+ozg+ySW35QeyheLtlgPR6wybmejcGsIPWC0odSUJEHWDcZphDOloBFkjc/XCMyM8quVGlJeZtXH378wBGLHho11UXyZ9PWVG1ArkZfVopM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1733850240; c=relaxed/simple; bh=RQvizUjBb/iiBoVKkcw/0RJ+LOxqNMarJAfCTsIS6ko=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=bjAer9MWT/wNGziqg1Wnctg54R3vwcVtMkfD+CSu9WumvpnJ+g3UIZxFCWFtwEtyeZbPmyrN5tOmufN3KDGGK1BbxXpPwkxSI0ox2NWRecA/R1rPaF1f4T/0qtye8U11QudCAWM6b1OnPw8EZ/uMcYPWwvxwXduEZfoH9JI5yyI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=HansenPartnership.com; spf=pass smtp.mailfrom=HansenPartnership.com; dkim=pass (1024-bit key) header.d=hansenpartnership.com header.i=@hansenpartnership.com header.b=mRsmtLAx; arc=none smtp.client-ip=96.44.175.130 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=HansenPartnership.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=HansenPartnership.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=hansenpartnership.com header.i=@hansenpartnership.com header.b="mRsmtLAx" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=hansenpartnership.com; s=20151216; t=1733850238; bh=RQvizUjBb/iiBoVKkcw/0RJ+LOxqNMarJAfCTsIS6ko=; h=From:To:Subject:Date:Message-Id:In-Reply-To:References:From; b=mRsmtLAxcesC0NgwFkDE4eQm6LiOouPpdOfwwVODd+cTY4ix/GvPrVFlTZTE5s9gX kYzUh/cW/mdDx3HSWDShkAK4Qyk4Z7rOFb5G7n8cG1wZl1E20ZnAPKQ9xjOXDOqfpr 2o91pc2Z9Yu5ZHwKqaopiArkNaIqRW1Ma7eDSqd8= Received: from localhost (localhost [127.0.0.1]) by bedivere.hansenpartnership.com (Postfix) with ESMTP id 8606E12819EA; Tue, 10 Dec 2024 12:03:58 -0500 (EST) Received: from bedivere.hansenpartnership.com ([127.0.0.1]) by localhost (bedivere.hansenpartnership.com [127.0.0.1]) (amavis, port 10024) with ESMTP id rYLrRsEEVGEz; Tue, 10 Dec 2024 12:03:58 -0500 (EST) Received: from lingrow.int.hansenpartnership.com (unknown [153.66.160.227]) by bedivere.hansenpartnership.com (Postfix) with ESMTP id D0D241281666; Tue, 10 Dec 2024 12:03:57 -0500 (EST) From: James Bottomley To: linux-fsdevel@vger.kernel.org, linux-efi@vger.kernel.org Cc: Ard Biesheuvel , Jeremy Kerr Subject: [PATCH 5/6] efivarfs: remove unused efivarfs_list Date: Tue, 10 Dec 2024 12:02:23 -0500 Message-Id: <20241210170224.19159-6-James.Bottomley@HansenPartnership.com> X-Mailer: git-send-email 2.35.3 In-Reply-To: <20241210170224.19159-1-James.Bottomley@HansenPartnership.com> References: <20241210170224.19159-1-James.Bottomley@HansenPartnership.com> Precedence: bulk X-Mailing-List: linux-efi@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Remove all function helpers and mentions of the efivarfs_list now that all consumers of the list have been removed and entry management goes exclusively through the inode. Signed-off-by: James Bottomley --- fs/efivarfs/inode.c | 5 --- fs/efivarfs/internal.h | 12 +----- fs/efivarfs/super.c | 15 ++----- fs/efivarfs/vars.c | 89 ++++++------------------------------------ 4 files changed, 16 insertions(+), 105 deletions(-) diff --git a/fs/efivarfs/inode.c b/fs/efivarfs/inode.c index 586446e02ef7..ad4f66e0d09d 100644 --- a/fs/efivarfs/inode.c +++ b/fs/efivarfs/inode.c @@ -77,7 +77,6 @@ bool efivarfs_valid_name(const char *str, int len) static int efivarfs_create(struct mnt_idmap *idmap, struct inode *dir, struct dentry *dentry, umode_t mode, bool excl) { - struct efivarfs_fs_info *info = dir->i_sb->s_fs_info; struct inode *inode = NULL; struct efivar_entry *var; int namelen, i = 0, err = 0; @@ -119,10 +118,6 @@ static int efivarfs_create(struct mnt_idmap *idmap, struct inode *dir, inode->i_private = var; kmemleak_ignore(var); - err = efivar_entry_add(var, &info->efivarfs_list); - if (err) - goto out; - d_instantiate(dentry, inode); dget(dentry); out: diff --git a/fs/efivarfs/internal.h b/fs/efivarfs/internal.h index d768bfa7f12b..e3816ec0e9d8 100644 --- a/fs/efivarfs/internal.h +++ b/fs/efivarfs/internal.h @@ -6,7 +6,6 @@ #ifndef EFIVAR_FS_INTERNAL_H #define EFIVAR_FS_INTERNAL_H -#include #include struct efivarfs_mount_opts { @@ -16,7 +15,6 @@ struct efivarfs_mount_opts { struct efivarfs_fs_info { struct efivarfs_mount_opts mount_opts; - struct list_head efivarfs_list; struct super_block *sb; struct notifier_block nb; }; @@ -28,15 +26,11 @@ struct efi_variable { struct efivar_entry { struct efi_variable var; - struct list_head list; }; -int efivar_init(int (*func)(efi_char16_t *, efi_guid_t, unsigned long, void *, - struct list_head *), - void *data, struct list_head *head); +int efivar_init(int (*func)(efi_char16_t *, efi_guid_t, unsigned long, void *), + void *data); -int efivar_entry_add(struct efivar_entry *entry, struct list_head *head); -void __efivar_entry_add(struct efivar_entry *entry, struct list_head *head); int efivar_entry_delete(struct efivar_entry *entry); int efivar_entry_size(struct efivar_entry *entry, unsigned long *size); @@ -47,8 +41,6 @@ int efivar_entry_get(struct efivar_entry *entry, u32 *attributes, int efivar_entry_set_get_size(struct efivar_entry *entry, u32 attributes, unsigned long *size, void *data, bool *set); -int efivar_entry_iter(int (*func)(struct efivar_entry *, void *), - struct list_head *head, void *data); bool efivar_validate(efi_guid_t vendor, efi_char16_t *var_name, u8 *data, unsigned long data_size); diff --git a/fs/efivarfs/super.c b/fs/efivarfs/super.c index 70b99f58c906..c9425a546691 100644 --- a/fs/efivarfs/super.c +++ b/fs/efivarfs/super.c @@ -43,10 +43,7 @@ static void efivarfs_evict_inode(struct inode *inode) { struct efivar_entry *entry = inode->i_private; - if (entry) { - list_del(&entry->list); - kfree(entry); - } + kfree(entry); clear_inode(inode); } @@ -208,8 +205,7 @@ bool efivarfs_variable_is_present(efi_char16_t *variable_name, } static int efivarfs_callback(efi_char16_t *name16, efi_guid_t vendor, - unsigned long name_size, void *data, - struct list_head *list) + unsigned long name_size, void *data) { struct super_block *sb = (struct super_block *)data; struct efivar_entry *entry; @@ -253,7 +249,6 @@ static int efivarfs_callback(efi_char16_t *name16, efi_guid_t vendor, } __efivar_entry_get(entry, NULL, &size, NULL); - __efivar_entry_add(entry, list); /* copied by the above to local storage in the dentry. */ kfree(name); @@ -344,7 +339,7 @@ static int efivarfs_fill_super(struct super_block *sb, struct fs_context *fc) if (err) return err; - return efivar_init(efivarfs_callback, sb, &sfi->efivarfs_list); + return efivar_init(efivarfs_callback, sb); } static int efivarfs_get_tree(struct fs_context *fc) @@ -379,8 +374,6 @@ static int efivarfs_init_fs_context(struct fs_context *fc) if (!sfi) return -ENOMEM; - INIT_LIST_HEAD(&sfi->efivarfs_list); - sfi->mount_opts.uid = GLOBAL_ROOT_UID; sfi->mount_opts.gid = GLOBAL_ROOT_GID; @@ -396,8 +389,6 @@ static void efivarfs_kill_sb(struct super_block *sb) blocking_notifier_chain_unregister(&efivar_ops_nh, &sfi->nb); kill_litter_super(sb); - /* Remove all entries and destroy */ - WARN_ON(!list_empty(&sfi->efivarfs_list)); kfree(sfi); } diff --git a/fs/efivarfs/vars.c b/fs/efivarfs/vars.c index bda8e8b869e8..4cac01a0e483 100644 --- a/fs/efivarfs/vars.c +++ b/fs/efivarfs/vars.c @@ -364,16 +364,14 @@ static void dup_variable_bug(efi_char16_t *str16, efi_guid_t *vendor_guid, * efivar_init - build the initial list of EFI variables * @func: callback function to invoke for every variable * @data: function-specific data to pass to @func - * @head: initialised head of variable list * * Get every EFI variable from the firmware and invoke @func. @func - * should call efivar_entry_add() to build the list of variables. + * should populate the initial dentry and inode tree. * * Returns 0 on success, or a kernel error code on failure. */ -int efivar_init(int (*func)(efi_char16_t *, efi_guid_t, unsigned long, void *, - struct list_head *), - void *data, struct list_head *head) +int efivar_init(int (*func)(efi_char16_t *, efi_guid_t, unsigned long, void *), + void *data) { unsigned long variable_name_size = 512; efi_char16_t *variable_name; @@ -424,7 +422,7 @@ int efivar_init(int (*func)(efi_char16_t *, efi_guid_t, unsigned long, void *, status = EFI_NOT_FOUND; } else { err = func(variable_name, vendor_guid, - variable_name_size, data, head); + variable_name_size, data); if (err) status = EFI_NOT_FOUND; } @@ -456,42 +454,12 @@ int efivar_init(int (*func)(efi_char16_t *, efi_guid_t, unsigned long, void *, } /** - * efivar_entry_add - add entry to variable list - * @entry: entry to add to list - * @head: list head - * - * Returns 0 on success, or a kernel error code on failure. - */ -int efivar_entry_add(struct efivar_entry *entry, struct list_head *head) -{ - int err; - - err = efivar_lock(); - if (err) - return err; - list_add(&entry->list, head); - efivar_unlock(); - - return 0; -} - -/** - * __efivar_entry_add - add entry to variable list - * @entry: entry to add to list - * @head: list head - */ -void __efivar_entry_add(struct efivar_entry *entry, struct list_head *head) -{ - list_add(&entry->list, head); -} - -/** - * efivar_entry_delete - delete variable and remove entry from list + * efivar_entry_delete - delete variable * @entry: entry containing variable to delete * - * Delete the variable from the firmware and remove @entry from the - * variable list. It is the caller's responsibility to free @entry - * once we return. + * Delete the variable from the firmware. It is the caller's + * responsibility to free @entry (by deleting the dentry/inode) once + * we return. * * Returns 0 on success, -EINTR if we can't grab the semaphore, * converted EFI status code if set_variable() fails. @@ -605,7 +573,7 @@ int efivar_entry_get(struct efivar_entry *entry, u32 *attributes, * get_variable() fail. * * If the EFI variable does not exist when calling set_variable() - * (EFI_NOT_FOUND), @entry is removed from the variable list. + * (EFI_NOT_FOUND). */ int efivar_entry_set_get_size(struct efivar_entry *entry, u32 attributes, unsigned long *size, void *data, bool *set) @@ -621,9 +589,8 @@ int efivar_entry_set_get_size(struct efivar_entry *entry, u32 attributes, return -EINVAL; /* - * The lock here protects the get_variable call, the conditional - * set_variable call, and removal of the variable from the efivars - * list (in the case of an authenticated delete). + * The lock here protects the get_variable call and the + * conditional set_variable call */ err = efivar_lock(); if (err) @@ -661,37 +628,3 @@ int efivar_entry_set_get_size(struct efivar_entry *entry, u32 attributes, return err; } - -/** - * efivar_entry_iter - iterate over variable list - * @func: callback function - * @head: head of variable list - * @data: function-specific data to pass to callback - * - * Iterate over the list of EFI variables and call @func with every - * entry on the list. It is safe for @func to remove entries in the - * list via efivar_entry_delete() while iterating. - * - * Some notes for the callback function: - * - a non-zero return value indicates an error and terminates the loop - * - @func is called from atomic context - */ -int efivar_entry_iter(int (*func)(struct efivar_entry *, void *), - struct list_head *head, void *data) -{ - struct efivar_entry *entry, *n; - int err = 0; - - err = efivar_lock(); - if (err) - return err; - - list_for_each_entry_safe(entry, n, head, list) { - err = func(entry, data); - if (err) - break; - } - efivar_unlock(); - - return err; -} From patchwork Tue Dec 10 17:02:24 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: James Bottomley X-Patchwork-Id: 848942 Received: from bedivere.hansenpartnership.com (bedivere.hansenpartnership.com [96.44.175.130]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 75ACE1BC09F; Tue, 10 Dec 2024 17:04:09 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=96.44.175.130 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1733850250; cv=none; b=K+u90X6A/wzbQ+Vi07hD8lQLb5duQmeVgilZ1qdKvEu1tI5O1tA4e3CwDIyc83iizgfnG2K1iYKyOd1/vssFONDd9tOCLFk7SOptvBu6ASEQI1dRcKrn5CXOIGAEhpc1N19fMxGP2Wj0+MoB0gP0b4aX/mJ0kmrnhHFPaTt7t0M= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1733850250; c=relaxed/simple; bh=OPxYu+JRY+hSaT08tIK0Mu9O8A/1onhr3l9stHMosLk=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=aQBGmXxt8aIs8mWXiiVwM57Xx0U42PneS/cQXJsrBa/28/3QbbiqYKDVE5Wv7z/k0g0dwvDMLRW/v/FHYloVZw1nB3caOL9yZFATYvSXhgqQMfCcDTiTf+VUS94mw5w84e+U7lhwZfZG9RHt6Dy18NOtBUzzFqDxi2sqe4c7M0g= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=HansenPartnership.com; spf=pass smtp.mailfrom=HansenPartnership.com; dkim=pass (1024-bit key) header.d=hansenpartnership.com header.i=@hansenpartnership.com header.b=FL+7cC82; arc=none smtp.client-ip=96.44.175.130 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=HansenPartnership.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=HansenPartnership.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=hansenpartnership.com header.i=@hansenpartnership.com header.b="FL+7cC82" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=hansenpartnership.com; s=20151216; t=1733850248; bh=OPxYu+JRY+hSaT08tIK0Mu9O8A/1onhr3l9stHMosLk=; h=From:To:Subject:Date:Message-Id:In-Reply-To:References:From; b=FL+7cC82YdywisEaU4wrHQe68rie6Dh4ZR/EFT9HlzqyrGupXj66LVahVbsKKJ/a7 WswozqsHgVrQiMtj6OrFSXyKnugxuHzqAd8iD081mx1TCpMKTojPXExS1zC0VZ5Ocx IkWfBTGcST3HQYb0B+QI6WEAA7x4RyH/YS2pEzVI= Received: from localhost (localhost [127.0.0.1]) by bedivere.hansenpartnership.com (Postfix) with ESMTP id 463481281701; Tue, 10 Dec 2024 12:04:08 -0500 (EST) Received: from bedivere.hansenpartnership.com ([127.0.0.1]) by localhost (bedivere.hansenpartnership.com [127.0.0.1]) (amavis, port 10024) with ESMTP id fOoGqsTqAgSo; Tue, 10 Dec 2024 12:04:08 -0500 (EST) Received: from lingrow.int.hansenpartnership.com (unknown [153.66.160.227]) by bedivere.hansenpartnership.com (Postfix) with ESMTP id 91E31128165E; Tue, 10 Dec 2024 12:04:07 -0500 (EST) From: James Bottomley To: linux-fsdevel@vger.kernel.org, linux-efi@vger.kernel.org Cc: Ard Biesheuvel , Jeremy Kerr Subject: [PATCH 6/6] efivarfs: fix error on write to new variable leaving remnants Date: Tue, 10 Dec 2024 12:02:24 -0500 Message-Id: <20241210170224.19159-7-James.Bottomley@HansenPartnership.com> X-Mailer: git-send-email 2.35.3 In-Reply-To: <20241210170224.19159-1-James.Bottomley@HansenPartnership.com> References: <20241210170224.19159-1-James.Bottomley@HansenPartnership.com> Precedence: bulk X-Mailing-List: linux-efi@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Make variable cleanup go through the fops release mechanism and use zero inode size as the indicator to delete the file. Since all EFI variables must have an initial u32 attribute, zero size occurs either because the update deleted the variable or because an unsuccessful write after create caused the size never to be set in the first place. Even though this fixes the bug that a create either not followed by a write or followed by a write that errored would leave a remnant file for the variable, the file will appear momentarily globally visible until the close of the fd deletes it. This is safe because the normal filesystem operations will mediate any races; however, it is still possible for a directory listing at that instant between create and close contain a variable that doesn't exist in the EFI table. Signed-off-by: James Bottomley --- fs/efivarfs/file.c | 31 ++++++++++++++++++++++--------- 1 file changed, 22 insertions(+), 9 deletions(-) diff --git a/fs/efivarfs/file.c b/fs/efivarfs/file.c index 23c51d62f902..edf363f395f5 100644 --- a/fs/efivarfs/file.c +++ b/fs/efivarfs/file.c @@ -38,22 +38,24 @@ static ssize_t efivarfs_file_write(struct file *file, bytes = efivar_entry_set_get_size(var, attributes, &datasize, data, &set); - if (!set && bytes) { + if (!set) { if (bytes == -ENOENT) bytes = -EIO; goto out; } + inode_lock(inode); if (bytes == -ENOENT) { - drop_nlink(inode); - d_delete(file->f_path.dentry); - dput(file->f_path.dentry); + /* + * zero size signals to release that the write deleted + * the variable + */ + i_size_write(inode, 0); } else { - inode_lock(inode); i_size_write(inode, datasize + sizeof(attributes)); inode_set_mtime_to_ts(inode, inode_set_ctime_current(inode)); - inode_unlock(inode); } + inode_unlock(inode); bytes = count; @@ -106,8 +108,19 @@ static ssize_t efivarfs_file_read(struct file *file, char __user *userbuf, return size; } +static int efivarfs_file_release(struct inode *inode, struct file *file) +{ + if (i_size_read(inode) == 0) { + drop_nlink(inode); + d_delete(file->f_path.dentry); + dput(file->f_path.dentry); + } + return 0; +} + const struct file_operations efivarfs_file_operations = { - .open = simple_open, - .read = efivarfs_file_read, - .write = efivarfs_file_write, + .open = simple_open, + .read = efivarfs_file_read, + .write = efivarfs_file_write, + .release = efivarfs_file_release, };