88#include <linux/efi.h>
99#include <linux/fs.h>
1010#include <linux/fs_context.h>
11+ #include <linux/fs_parser.h>
1112#include <linux/module.h>
1213#include <linux/pagemap.h>
1314#include <linux/ucs2_string.h>
@@ -24,6 +25,21 @@ static void efivarfs_evict_inode(struct inode *inode)
2425 clear_inode (inode );
2526}
2627
28+ static int efivarfs_show_options (struct seq_file * m , struct dentry * root )
29+ {
30+ struct super_block * sb = root -> d_sb ;
31+ struct efivarfs_fs_info * sbi = sb -> s_fs_info ;
32+ struct efivarfs_mount_opts * opts = & sbi -> mount_opts ;
33+
34+ if (!uid_eq (opts -> uid , GLOBAL_ROOT_UID ))
35+ seq_printf (m , ",uid=%u" ,
36+ from_kuid_munged (& init_user_ns , opts -> uid ));
37+ if (!gid_eq (opts -> gid , GLOBAL_ROOT_GID ))
38+ seq_printf (m , ",gid=%u" ,
39+ from_kgid_munged (& init_user_ns , opts -> gid ));
40+ return 0 ;
41+ }
42+
2743static int efivarfs_statfs (struct dentry * dentry , struct kstatfs * buf )
2844{
2945 const u32 attr = EFI_VARIABLE_NON_VOLATILE |
@@ -70,6 +86,7 @@ static const struct super_operations efivarfs_ops = {
7086 .statfs = efivarfs_statfs ,
7187 .drop_inode = generic_delete_inode ,
7288 .evict_inode = efivarfs_evict_inode ,
89+ .show_options = efivarfs_show_options ,
7390};
7491
7592/*
@@ -231,6 +248,45 @@ static int efivarfs_destroy(struct efivar_entry *entry, void *data)
231248 return 0 ;
232249}
233250
251+ enum {
252+ Opt_uid , Opt_gid ,
253+ };
254+
255+ static const struct fs_parameter_spec efivarfs_parameters [] = {
256+ fsparam_u32 ("uid" , Opt_uid ),
257+ fsparam_u32 ("gid" , Opt_gid ),
258+ {},
259+ };
260+
261+ static int efivarfs_parse_param (struct fs_context * fc , struct fs_parameter * param )
262+ {
263+ struct efivarfs_fs_info * sbi = fc -> s_fs_info ;
264+ struct efivarfs_mount_opts * opts = & sbi -> mount_opts ;
265+ struct fs_parse_result result ;
266+ int opt ;
267+
268+ opt = fs_parse (fc , efivarfs_parameters , param , & result );
269+ if (opt < 0 )
270+ return opt ;
271+
272+ switch (opt ) {
273+ case Opt_uid :
274+ opts -> uid = make_kuid (current_user_ns (), result .uint_32 );
275+ if (!uid_valid (opts -> uid ))
276+ return - EINVAL ;
277+ break ;
278+ case Opt_gid :
279+ opts -> gid = make_kgid (current_user_ns (), result .uint_32 );
280+ if (!gid_valid (opts -> gid ))
281+ return - EINVAL ;
282+ break ;
283+ default :
284+ return - EINVAL ;
285+ }
286+
287+ return 0 ;
288+ }
289+
234290static int efivarfs_fill_super (struct super_block * sb , struct fs_context * fc )
235291{
236292 struct inode * inode = NULL ;
@@ -277,10 +333,21 @@ static int efivarfs_get_tree(struct fs_context *fc)
277333
278334static const struct fs_context_operations efivarfs_context_ops = {
279335 .get_tree = efivarfs_get_tree ,
336+ .parse_param = efivarfs_parse_param ,
280337};
281338
282339static int efivarfs_init_fs_context (struct fs_context * fc )
283340{
341+ struct efivarfs_fs_info * sfi ;
342+
343+ sfi = kzalloc (sizeof (* sfi ), GFP_KERNEL );
344+ if (!sfi )
345+ return - ENOMEM ;
346+
347+ sfi -> mount_opts .uid = GLOBAL_ROOT_UID ;
348+ sfi -> mount_opts .gid = GLOBAL_ROOT_GID ;
349+
350+ fc -> s_fs_info = sfi ;
284351 fc -> ops = & efivarfs_context_ops ;
285352 return 0 ;
286353}
@@ -301,6 +368,7 @@ static struct file_system_type efivarfs_type = {
301368 .name = "efivarfs" ,
302369 .init_fs_context = efivarfs_init_fs_context ,
303370 .kill_sb = efivarfs_kill_sb ,
371+ .parameters = efivarfs_parameters ,
304372};
305373
306374static __init int efivarfs_init (void )
0 commit comments