1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (C) 2012 Red Hat, Inc.
4 * Copyright (C) 2012 Jeremy Kerr <jeremy.kerr@canonical.com>
7 #include <linux/ctype.h>
10 #include <linux/fs_context.h>
11 #include <linux/fs_parser.h>
12 #include <linux/module.h>
13 #include <linux/pagemap.h>
14 #include <linux/ucs2_string.h>
15 #include <linux/slab.h>
16 #include <linux/suspend.h>
17 #include <linux/magic.h>
18 #include <linux/statfs.h>
19 #include <linux/notifier.h>
20 #include <linux/printk.h>
24 static int efivarfs_ops_notifier(struct notifier_block
*nb
, unsigned long event
,
27 struct efivarfs_fs_info
*sfi
= container_of(nb
, struct efivarfs_fs_info
, nb
);
30 case EFIVAR_OPS_RDONLY
:
31 sfi
->sb
->s_flags
|= SB_RDONLY
;
34 sfi
->sb
->s_flags
&= ~SB_RDONLY
;
43 static struct inode
*efivarfs_alloc_inode(struct super_block
*sb
)
45 struct efivar_entry
*entry
= kzalloc(sizeof(*entry
), GFP_KERNEL
);
50 inode_init_once(&entry
->vfs_inode
);
51 entry
->removed
= false;
53 return &entry
->vfs_inode
;
56 static void efivarfs_free_inode(struct inode
*inode
)
58 struct efivar_entry
*entry
= efivar_entry(inode
);
63 static int efivarfs_show_options(struct seq_file
*m
, struct dentry
*root
)
65 struct super_block
*sb
= root
->d_sb
;
66 struct efivarfs_fs_info
*sbi
= sb
->s_fs_info
;
67 struct efivarfs_mount_opts
*opts
= &sbi
->mount_opts
;
69 if (!uid_eq(opts
->uid
, GLOBAL_ROOT_UID
))
70 seq_printf(m
, ",uid=%u",
71 from_kuid_munged(&init_user_ns
, opts
->uid
));
72 if (!gid_eq(opts
->gid
, GLOBAL_ROOT_GID
))
73 seq_printf(m
, ",gid=%u",
74 from_kgid_munged(&init_user_ns
, opts
->gid
));
78 static int efivarfs_statfs(struct dentry
*dentry
, struct kstatfs
*buf
)
80 const u32 attr
= EFI_VARIABLE_NON_VOLATILE
|
81 EFI_VARIABLE_BOOTSERVICE_ACCESS
|
82 EFI_VARIABLE_RUNTIME_ACCESS
;
83 u64 storage_space
, remaining_space
, max_variable_size
;
84 u64 id
= huge_encode_dev(dentry
->d_sb
->s_dev
);
87 /* Some UEFI firmware does not implement QueryVariableInfo() */
88 storage_space
= remaining_space
= 0;
89 if (efi_rt_services_supported(EFI_RT_SUPPORTED_QUERY_VARIABLE_INFO
)) {
90 status
= efivar_query_variable_info(attr
, &storage_space
,
93 if (status
!= EFI_SUCCESS
&& status
!= EFI_UNSUPPORTED
)
94 pr_warn_ratelimited("query_variable_info() failed: 0x%lx\n",
99 * This is not a normal filesystem, so no point in pretending it has a block
100 * size; we declare f_bsize to 1, so that we can then report the exact value
101 * sent by EFI QueryVariableInfo in f_blocks and f_bfree
104 buf
->f_namelen
= NAME_MAX
;
105 buf
->f_blocks
= storage_space
;
106 buf
->f_bfree
= remaining_space
;
107 buf
->f_type
= dentry
->d_sb
->s_magic
;
108 buf
->f_fsid
= u64_to_fsid(id
);
111 * In f_bavail we declare the free space that the kernel will allow writing
112 * when the storage_paranoia x86 quirk is active. To use more, users
113 * should boot the kernel with efi_no_storage_paranoia.
115 if (remaining_space
> efivar_reserved_space())
116 buf
->f_bavail
= remaining_space
- efivar_reserved_space();
122 static const struct super_operations efivarfs_ops
= {
123 .statfs
= efivarfs_statfs
,
124 .drop_inode
= generic_delete_inode
,
125 .alloc_inode
= efivarfs_alloc_inode
,
126 .free_inode
= efivarfs_free_inode
,
127 .show_options
= efivarfs_show_options
,
131 * Compare two efivarfs file names.
133 * An efivarfs filename is composed of two parts,
135 * 1. A case-sensitive variable name
136 * 2. A case-insensitive GUID
138 * So we need to perform a case-sensitive match on part 1 and a
139 * case-insensitive match on part 2.
141 static int efivarfs_d_compare(const struct dentry
*dentry
,
142 unsigned int len
, const char *str
,
143 const struct qstr
*name
)
145 int guid
= len
- EFI_VARIABLE_GUID_LEN
;
147 if (name
->len
!= len
)
150 /* Case-sensitive compare for the variable name */
151 if (memcmp(str
, name
->name
, guid
))
154 /* Case-insensitive compare for the GUID */
155 return strncasecmp(name
->name
+ guid
, str
+ guid
, EFI_VARIABLE_GUID_LEN
);
158 static int efivarfs_d_hash(const struct dentry
*dentry
, struct qstr
*qstr
)
160 unsigned long hash
= init_name_hash(dentry
);
161 const unsigned char *s
= qstr
->name
;
162 unsigned int len
= qstr
->len
;
164 while (len
-- > EFI_VARIABLE_GUID_LEN
)
165 hash
= partial_name_hash(*s
++, hash
);
167 /* GUID is case-insensitive. */
169 hash
= partial_name_hash(tolower(*s
++), hash
);
171 qstr
->hash
= end_name_hash(hash
);
175 static const struct dentry_operations efivarfs_d_ops
= {
176 .d_compare
= efivarfs_d_compare
,
177 .d_hash
= efivarfs_d_hash
,
178 .d_delete
= always_delete_dentry
,
181 static struct dentry
*efivarfs_alloc_dentry(struct dentry
*parent
, char *name
)
188 q
.len
= strlen(name
);
190 err
= efivarfs_d_hash(parent
, &q
);
194 d
= d_alloc(parent
, &q
);
198 return ERR_PTR(-ENOMEM
);
201 bool efivarfs_variable_is_present(efi_char16_t
*variable_name
,
202 efi_guid_t
*vendor
, void *data
)
204 char *name
= efivar_get_utf8name(variable_name
, vendor
);
205 struct super_block
*sb
= data
;
206 struct dentry
*dentry
;
211 * If the allocation failed there'll already be an
212 * error in the log (and likely a huge and growing
213 * number of them since they system will be under
214 * extreme memory pressure), so simply assume
215 * collision for safety but don't add to the log
221 qstr
.len
= strlen(name
);
222 dentry
= d_hash_and_lookup(sb
->s_root
, &qstr
);
224 if (!IS_ERR_OR_NULL(dentry
))
227 return dentry
!= NULL
;
230 static int efivarfs_create_dentry(struct super_block
*sb
, efi_char16_t
*name16
,
231 unsigned long name_size
, efi_guid_t vendor
,
234 struct efivar_entry
*entry
;
236 struct dentry
*dentry
, *root
= sb
->s_root
;
237 unsigned long size
= 0;
240 bool is_removable
= false;
242 /* length of the variable name itself: remove GUID and separator */
243 len
= strlen(name
) - EFI_VARIABLE_GUID_LEN
- 1;
245 if (efivar_variable_is_removable(vendor
, name
, len
))
248 inode
= efivarfs_get_inode(sb
, d_inode(root
), S_IFREG
| 0644, 0,
253 entry
= efivar_entry(inode
);
255 memcpy(entry
->var
.VariableName
, name16
, name_size
);
256 memcpy(&(entry
->var
.VendorGuid
), &vendor
, sizeof(efi_guid_t
));
258 dentry
= efivarfs_alloc_dentry(root
, name
);
259 if (IS_ERR(dentry
)) {
260 err
= PTR_ERR(dentry
);
264 __efivar_entry_get(entry
, NULL
, &size
, NULL
);
266 /* copied by the above to local storage in the dentry. */
270 inode
->i_private
= entry
;
271 i_size_write(inode
, size
+ sizeof(__u32
)); /* attributes + data */
273 d_add(dentry
, inode
);
285 static int efivarfs_callback(efi_char16_t
*name16
, efi_guid_t vendor
,
286 unsigned long name_size
, void *data
)
288 struct super_block
*sb
= (struct super_block
*)data
;
291 if (guid_equal(&vendor
, &LINUX_EFI_RANDOM_SEED_TABLE_GUID
))
294 name
= efivar_get_utf8name(name16
, &vendor
);
298 return efivarfs_create_dentry(sb
, name16
, name_size
, vendor
, name
);
305 static const struct fs_parameter_spec efivarfs_parameters
[] = {
306 fsparam_uid("uid", Opt_uid
),
307 fsparam_gid("gid", Opt_gid
),
311 static int efivarfs_parse_param(struct fs_context
*fc
, struct fs_parameter
*param
)
313 struct efivarfs_fs_info
*sbi
= fc
->s_fs_info
;
314 struct efivarfs_mount_opts
*opts
= &sbi
->mount_opts
;
315 struct fs_parse_result result
;
318 opt
= fs_parse(fc
, efivarfs_parameters
, param
, &result
);
324 opts
->uid
= result
.uid
;
327 opts
->gid
= result
.gid
;
336 static int efivarfs_fill_super(struct super_block
*sb
, struct fs_context
*fc
)
338 struct efivarfs_fs_info
*sfi
= sb
->s_fs_info
;
339 struct inode
*inode
= NULL
;
343 sb
->s_maxbytes
= MAX_LFS_FILESIZE
;
344 sb
->s_blocksize
= PAGE_SIZE
;
345 sb
->s_blocksize_bits
= PAGE_SHIFT
;
346 sb
->s_magic
= EFIVARFS_MAGIC
;
347 sb
->s_op
= &efivarfs_ops
;
348 sb
->s_d_op
= &efivarfs_d_ops
;
351 if (!efivar_supports_writes())
352 sb
->s_flags
|= SB_RDONLY
;
354 inode
= efivarfs_get_inode(sb
, NULL
, S_IFDIR
| 0755, 0, true);
357 inode
->i_op
= &efivarfs_dir_inode_operations
;
359 root
= d_make_root(inode
);
365 sfi
->nb
.notifier_call
= efivarfs_ops_notifier
;
366 err
= blocking_notifier_chain_register(&efivar_ops_nh
, &sfi
->nb
);
370 return efivar_init(efivarfs_callback
, sb
, true);
373 static int efivarfs_get_tree(struct fs_context
*fc
)
375 return get_tree_single(fc
, efivarfs_fill_super
);
378 static int efivarfs_reconfigure(struct fs_context
*fc
)
380 if (!efivar_supports_writes() && !(fc
->sb_flags
& SB_RDONLY
)) {
381 pr_err("Firmware does not support SetVariableRT. Can not remount with rw\n");
388 static const struct fs_context_operations efivarfs_context_ops
= {
389 .get_tree
= efivarfs_get_tree
,
390 .parse_param
= efivarfs_parse_param
,
391 .reconfigure
= efivarfs_reconfigure
,
394 struct efivarfs_ctx
{
395 struct dir_context ctx
;
396 struct super_block
*sb
;
397 struct dentry
*dentry
;
400 static bool efivarfs_actor(struct dir_context
*ctx
, const char *name
, int len
,
401 loff_t offset
, u64 ino
, unsigned mode
)
404 struct efivarfs_ctx
*ectx
= container_of(ctx
, struct efivarfs_ctx
, ctx
);
405 struct qstr qstr
= { .name
= name
, .len
= len
};
406 struct dentry
*dentry
= d_hash_and_lookup(ectx
->sb
->s_root
, &qstr
);
408 struct efivar_entry
*entry
;
411 if (IS_ERR_OR_NULL(dentry
))
414 inode
= d_inode(dentry
);
415 entry
= efivar_entry(inode
);
417 err
= efivar_entry_size(entry
, &size
);
418 size
+= sizeof(__u32
); /* attributes */
423 i_size_write(inode
, size
);
427 ectx
->dentry
= dentry
;
436 static int efivarfs_check_missing(efi_char16_t
*name16
, efi_guid_t vendor
,
437 unsigned long name_size
, void *data
)
440 struct super_block
*sb
= data
;
441 struct dentry
*dentry
;
445 if (guid_equal(&vendor
, &LINUX_EFI_RANDOM_SEED_TABLE_GUID
))
448 name
= efivar_get_utf8name(name16
, &vendor
);
453 qstr
.len
= strlen(name
);
454 dentry
= d_hash_and_lookup(sb
->s_root
, &qstr
);
455 if (IS_ERR(dentry
)) {
456 err
= PTR_ERR(dentry
);
461 /* found missing entry */
462 pr_info("efivarfs: creating variable %s\n", name
);
463 return efivarfs_create_dentry(sb
, name16
, name_size
, vendor
, name
);
475 static int efivarfs_pm_notify(struct notifier_block
*nb
, unsigned long action
,
478 struct efivarfs_fs_info
*sfi
= container_of(nb
, struct efivarfs_fs_info
,
480 struct path path
= { .mnt
= NULL
, .dentry
= sfi
->sb
->s_root
, };
481 struct efivarfs_ctx ectx
= {
483 .actor
= efivarfs_actor
,
488 static bool rescan_done
= true;
490 if (action
== PM_HIBERNATION_PREPARE
) {
493 } else if (action
!= PM_POST_HIBERNATION
) {
500 pr_info("efivarfs: resyncing variable state\n");
502 /* O_NOATIME is required to prevent oops on NULL mnt */
503 file
= kernel_file_open(&path
, O_RDONLY
| O_DIRECTORY
| O_NOATIME
,
511 * First loop over the directory and verify each entry exists,
512 * removing it if it doesn't
514 file
->f_pos
= 2; /* skip . and .. */
517 iterate_dir(file
, &ectx
.ctx
);
519 pr_info("efivarfs: removing variable %pd\n",
521 simple_recursive_removal(ectx
.dentry
, NULL
);
524 } while (ectx
.dentry
);
528 * then loop over variables, creating them if there's no matching
531 efivar_init(efivarfs_check_missing
, sfi
->sb
, false);
536 static int efivarfs_init_fs_context(struct fs_context
*fc
)
538 struct efivarfs_fs_info
*sfi
;
540 if (!efivar_is_available())
543 sfi
= kzalloc(sizeof(*sfi
), GFP_KERNEL
);
547 sfi
->mount_opts
.uid
= GLOBAL_ROOT_UID
;
548 sfi
->mount_opts
.gid
= GLOBAL_ROOT_GID
;
551 fc
->ops
= &efivarfs_context_ops
;
553 sfi
->pm_nb
.notifier_call
= efivarfs_pm_notify
;
554 sfi
->pm_nb
.priority
= 0;
555 register_pm_notifier(&sfi
->pm_nb
);
560 static void efivarfs_kill_sb(struct super_block
*sb
)
562 struct efivarfs_fs_info
*sfi
= sb
->s_fs_info
;
564 blocking_notifier_chain_unregister(&efivar_ops_nh
, &sfi
->nb
);
565 kill_litter_super(sb
);
566 unregister_pm_notifier(&sfi
->pm_nb
);
571 static struct file_system_type efivarfs_type
= {
572 .owner
= THIS_MODULE
,
574 .init_fs_context
= efivarfs_init_fs_context
,
575 .kill_sb
= efivarfs_kill_sb
,
576 .parameters
= efivarfs_parameters
,
579 static __init
int efivarfs_init(void)
581 return register_filesystem(&efivarfs_type
);
584 static __exit
void efivarfs_exit(void)
586 unregister_filesystem(&efivarfs_type
);
589 MODULE_AUTHOR("Matthew Garrett, Jeremy Kerr");
590 MODULE_DESCRIPTION("EFI Variable Filesystem");
591 MODULE_LICENSE("GPL");
592 MODULE_ALIAS_FS("efivarfs");
594 module_init(efivarfs_init
);
595 module_exit(efivarfs_exit
);