PowerVM provides an isolated Platform KeyStore (PKS)[1] storage allocation
for each logical partition (LPAR) with individually managed access controls
to store sensitive information securely. The Linux kernel can access this
storage by interfacing with the hypervisor using a new set of hypervisor
calls.
The PowerVM guest secure boot feature intends to use PKS for the purpose of
storing public keys. Secure boot requires public keys in order to verify
GRUB and the boot kernel. To allow authenticated manipulation of keys, PKS
supports variables to store key authorities namely, PK and KEK. Other
variables are used to store code signing keys, db and grubdb. It also
supports deny lists to disallow booting GRUB or kernels even if they are
signed with valid keys. This is done via deny list databases stored in dbx
and sbat variables. These variables are stored in PKS and are managed and
controlled by firmware.
The purpose of this patchset is to add the userspace interface to manage
these variables.
Currently, OpenPOWER exposes variables via sysfs, while EFI platforms have
used sysfs and then moved to their own efivarfs filesystem. The recent
coco feature uses securityfs to expose secrets to TEEs. All of these
environments are different both syntactically and semantically.
securityfs is meant for Linux security subsystems to expose policies, logs,
and other information and it does not interact with firmware for managing
these variables. However, there are various firmware security features that
expose their variables for user management via pseudo filesystems as
discussed above. There is currently no single place to expose these
variables. Different platforms use sysfs, platform-specific filesystems
such as efivars, or securityfs as they have found appropriate. This has
resulted in interfaces scattered around the tree. The multiple interfac
problem can be addressed by providing a single pseudo filesystem for all
platforms to expose their variables for firmware security features. Doing
so simplifies the interface for users of these platforms.
This patchset introduces a new firmware security pseudo filesystem,
fwsecurityfs. Any platform can expose the variables that are required by
firmware security features via this interface. It provides a common place
for exposing variables managed by firmware while still allowing platforms
to implement their own underlying semantics.
This design consists of two parts:
1. Firmware security filesystem (fwsecurityfs) that provides platforms
with APIs to create their own underlying directory and file structure.
It should be mounted on a new well-known mountpoint,
/sys/firmware/security.
2. Platform-specific layer for these variables that implements underlying
semantics. Platforms can expose their variables as files allowing
read/write/add/delete operations by defining their own inode and file
functions.
This patchset adds:
1. An update to the PLPKS driver to support the signed update H_CALL for
authenticated variables used in guest secure boot.
2. A firmware security filesystem named fwsecurityfs.
3. An interface to expose secure variables stored in the LPAR's PKS via
fwsecurityfs.
Note: This patchset is not intended to modify existing interfaces already
used by OpenPOWER or EFI but rather to ensure that new similar interfaces
have a common base going forward.
The first patch related to PLPKS driver is dependent on bugfixes posted
as part of patchset[4].
Changelog:
First non-RFC version after RFC versions[2,3].
Feedback from non-RFC version are included to update fwsecurityfs.
* PLPKS driver patch had been upstreamed separately. In this set, Patch 1
updates existing driver to include signed update support.
* Fix fwsecurityfs to also pin the file system, refactor and cleanup. The
consideration of namespacing has been done and is concluded that currently
no firmware object or entity is handled by namespacing. The purpose of
fwsecurityfs is to expose firmware space which is similar to exposing
space in TPM. And TPM is also not currently namespaced. If containers have
to make use of some such space in the future, it would have to be some
software space. With that, this currently only considers the host using the
firmware space.
* Fix secvars support for powerpc. It supports policy handling within the
kernel, supports UCS2 naming and cleanups.
* Read-only PLPKS configuration is exposed.
* secvars directory is now moved within a new parent directory plpks.
* Patch is now no more an RFC version.
[1] https://community.ibm.com/community/user/power/blogs/chris-engel1/2020/11/20/powervm-introduces-the-platform-keystore
[2] RFC v2: https://lore.kernel.org/linuxppc-dev/20220622215648.96723-1-nayna@linux.ibm.com/
[3] RFC v1: https://lore.kernel.org/linuxppc-dev/20220122005637.28199-1-nayna@linux.ibm.com/
[4] https://lore.kernel.org/linuxppc-dev/20221106205839.600442-1-nayna@linux.ibm.com/T/#t
Nayna Jain (4):
powerpc/pseries: Add new functions to PLPKS driver
fs: define a firmware security filesystem named fwsecurityfs
powerpc/pseries: initialize fwsecurityfs with plpks arch-specific
structure
powerpc/pseries: expose authenticated variables stored in LPAR PKS
arch/powerpc/include/asm/hvcall.h | 3 +-
arch/powerpc/platforms/pseries/Kconfig | 20 +
arch/powerpc/platforms/pseries/Makefile | 2 +
.../platforms/pseries/fwsecurityfs_arch.c | 124 ++++++
arch/powerpc/platforms/pseries/plpks.c | 112 +++++-
arch/powerpc/platforms/pseries/plpks.h | 38 ++
arch/powerpc/platforms/pseries/secvars.c | 365 ++++++++++++++++++
fs/Kconfig | 1 +
fs/Makefile | 1 +
fs/fwsecurityfs/Kconfig | 14 +
fs/fwsecurityfs/Makefile | 10 +
fs/fwsecurityfs/super.c | 263 +++++++++++++
include/linux/fwsecurityfs.h | 33 ++
include/uapi/linux/magic.h | 1 +
14 files changed, 981 insertions(+), 6 deletions(-)
create mode 100644 arch/powerpc/platforms/pseries/fwsecurityfs_arch.c
create mode 100644 arch/powerpc/platforms/pseries/secvars.c
create mode 100644 fs/fwsecurityfs/Kconfig
create mode 100644 fs/fwsecurityfs/Makefile
create mode 100644 fs/fwsecurityfs/super.c
create mode 100644 include/linux/fwsecurityfs.h
--
2.31.1
securityfs is meant for Linux security subsystems to expose policies/logs
or any other information. However, there are various firmware security
features which expose their variables for user management via the kernel.
There is currently no single place to expose these variables. Different
platforms use sysfs/platform specific filesystem(efivarfs)/securityfs
interface as they find it appropriate. Thus, there is a gap in kernel
interfaces to expose variables for security features.
Define a firmware security filesystem (fwsecurityfs) to be used by
security features enabled by the firmware. These variables are platform
specific. This filesystem provides platforms a way to implement their
own underlying semantics by defining own inode and file operations.
Similar to securityfs, the firmware security filesystem is recommended
to be exposed on a well known mount point /sys/firmware/security.
Platforms can define their own directory or file structure under this path.
Example:
# mount -t fwsecurityfs fwsecurityfs /sys/firmware/security
# cd /sys/firmware/security/
Signed-off-by: Nayna Jain <nayna@linux.ibm.com>
---
fs/Kconfig | 1 +
fs/Makefile | 1 +
fs/fwsecurityfs/Kconfig | 14 ++
fs/fwsecurityfs/Makefile | 10 ++
fs/fwsecurityfs/super.c | 263 +++++++++++++++++++++++++++++++++++
include/linux/fwsecurityfs.h | 29 ++++
include/uapi/linux/magic.h | 1 +
7 files changed, 319 insertions(+)
create mode 100644 fs/fwsecurityfs/Kconfig
create mode 100644 fs/fwsecurityfs/Makefile
create mode 100644 fs/fwsecurityfs/super.c
create mode 100644 include/linux/fwsecurityfs.h
@@ -0,0 +1,263 @@+// SPDX-License-Identifier: GPL-2.0-only+/*+*Copyright(C)2022IBMCorporation+*Author:NaynaJain<nayna@linux.ibm.com>+*/++#include<linux/fs.h>+#include<linux/fs_context.h>+#include<linux/pagemap.h>+#include<linux/init.h>+#include<linux/namei.h>+#include<linux/magic.h>+#include<linux/fwsecurityfs.h>++staticstructsuper_block*fwsecsb;+staticstructvfsmount*mount;+staticintmount_count;+staticboolfwsecurityfs_initialized;++staticvoidfwsecurityfs_free_inode(structinode*inode)+{+free_inode_nonrcu(inode);+}++staticconststructsuper_operationsfwsecurityfs_super_operations={+.statfs=simple_statfs,+.free_inode=fwsecurityfs_free_inode,+};++staticintfwsecurityfs_fill_super(structsuper_block*sb,+structfs_context*fc)+{+staticconststructtree_descrfiles[]={{""}};+intrc;++rc=simple_fill_super(sb,FWSECURITYFS_MAGIC,files);+if(rc)+returnrc;++sb->s_op=&fwsecurityfs_super_operations;++fwsecsb=sb;++rc=arch_fwsecurityfs_init();++if(!rc)+fwsecurityfs_initialized=true;++returnrc;+}++staticintfwsecurityfs_get_tree(structfs_context*fc)+{+returnget_tree_single(fc,fwsecurityfs_fill_super);+}++staticconststructfs_context_operationsfwsecurityfs_context_ops={+.get_tree=fwsecurityfs_get_tree,+};++staticintfwsecurityfs_init_fs_context(structfs_context*fc)+{+fc->ops=&fwsecurityfs_context_ops;++return0;+}++staticvoidfwsecurityfs_kill_sb(structsuper_block*sb)+{+kill_litter_super(sb);++fwsecurityfs_initialized=false;+}++staticstructfile_system_typefs_type={+.owner=THIS_MODULE,+.name="fwsecurityfs",+.init_fs_context=fwsecurityfs_init_fs_context,+.kill_sb=fwsecurityfs_kill_sb,+};++staticstructdentry*fwsecurityfs_create_dentry(constchar*name,umode_tmode,+u16filesize,+structdentry*parent,+structdentry*dentry,void*data,+conststructfile_operations*fops,+conststructinode_operations*iops)+{+structinode*inode;+intrc;+structinode*dir;+structdentry*ldentry=dentry;++/* Calling simple_pin_fs() while initial mount in progress results in recursive+*calltomount.+*/+if(fwsecurityfs_initialized){+rc=simple_pin_fs(&fs_type,&mount,&mount_count);+if(rc)+returnERR_PTR(rc);+}++dir=d_inode(parent);++/* For userspace created files, lock is already taken. */+if(!dentry)+inode_lock(dir);++if(!dentry){+ldentry=lookup_one_len(name,parent,strlen(name));+if(IS_ERR(ldentry))+gotoout;++if(d_really_is_positive(ldentry)){+rc=-EEXIST;+gotoout1;+}+}++inode=new_inode(dir->i_sb);+if(!inode){+rc=-ENOMEM;+gotoout1;+}++inode->i_ino=get_next_ino();+inode->i_mode=mode;+inode->i_atime=current_time(inode);+inode->i_mtime=current_time(inode);+inode->i_ctime=current_time(inode);+inode->i_private=data;++if(S_ISDIR(mode)){+inode->i_op=iops?iops:&simple_dir_inode_operations;+inode->i_fop=&simple_dir_operations;+inc_nlink(inode);+inc_nlink(dir);+}else{+inode->i_fop=fops?fops:&simple_dir_operations;+}++if(S_ISREG(mode)){+inode_lock(inode);+i_size_write(inode,filesize);+inode_unlock(inode);+}+d_instantiate(ldentry,inode);++/* dget() here is required for userspace created files. */+if(dentry)+dget(ldentry);++if(!dentry)+inode_unlock(dir);++returnldentry;++out1:+ldentry=ERR_PTR(rc);++out:+if(fwsecurityfs_initialized)+simple_release_fs(&mount,&mount_count);++if(!dentry)+inode_unlock(dir);++returnldentry;+}++structdentry*fwsecurityfs_create_file(constchar*name,umode_tmode,+u16filesize,structdentry*parent,+structdentry*dentry,void*data,+conststructfile_operations*fops)+{+if(!parent)+returnERR_PTR(-EINVAL);++returnfwsecurityfs_create_dentry(name,mode,filesize,parent,+dentry,data,fops,NULL);+}+EXPORT_SYMBOL_GPL(fwsecurityfs_create_file);++structdentry*fwsecurityfs_create_dir(constchar*name,umode_tmode,+structdentry*parent,+conststructinode_operations*iops)+{+if(!parent){+if(!fwsecsb)+returnERR_PTR(-EIO);+parent=fwsecsb->s_root;+}++returnfwsecurityfs_create_dentry(name,mode,0,parent,NULL,NULL,+NULL,iops);+}+EXPORT_SYMBOL_GPL(fwsecurityfs_create_dir);++staticintfwsecurityfs_remove_dentry(structdentry*dentry)+{+structinode*dir;++if(!dentry||IS_ERR(dentry))+return-EINVAL;++dir=d_inode(dentry->d_parent);+inode_lock(dir);+if(simple_positive(dentry)){+dget(dentry);+if(d_is_dir(dentry))+simple_rmdir(dir,dentry);+else+simple_unlink(dir,dentry);+d_delete(dentry);+dput(dentry);+}+inode_unlock(dir);++/* Once fwsecurityfs_initialized is set to true, calling this for+*removingfilescreatedduringinitialmountmightresultin+*imbalanceofsimple_pin_fs()andsimple_release_fs()calls.+*/+if(fwsecurityfs_initialized)+simple_release_fs(&mount,&mount_count);++return0;+}++intfwsecurityfs_remove_dir(structdentry*dentry)+{+if(!d_is_dir(dentry))+return-EPERM;++returnfwsecurityfs_remove_dentry(dentry);+}+EXPORT_SYMBOL_GPL(fwsecurityfs_remove_dir);++intfwsecurityfs_remove_file(structdentry*dentry)+{+returnfwsecurityfs_remove_dentry(dentry);+};+EXPORT_SYMBOL_GPL(fwsecurityfs_remove_file);++staticint__initfwsecurityfs_init(void)+{+intrc;++rc=sysfs_create_mount_point(firmware_kobj,"security");+if(rc)+returnrc;++rc=register_filesystem(&fs_type);+if(rc){+sysfs_remove_mount_point(firmware_kobj,"security");+returnrc;+}++return0;+}+core_initcall(fwsecurityfs_init);+MODULE_DESCRIPTION("Firmware Security Filesystem");+MODULE_AUTHOR("Nayna Jain");+MODULE_LICENSE("GPL");
@@ -172,6 +172,16 @@ config PSERIES_FWSECURITYFS_ARCHIfyouareunsurehowtouseit,sayN.+configPSERIES_PLPKS_SECVARS+depends onPSERIES_PLPKS+selectPSERIES_FWSECURITYFS_ARCH+tristate"Support for secvars"+help+ThisinterfaceexposesauthenticatedvariablesstoredintheLPAR+PlatformKeyStoreusingfwsecurityfsinterface.++Ifyouareunsurehowtouseit,sayN.+configPAPR_SCMdepends onPPC_PSERIES&&MEMORY_HOTPLUG&&LIBNVDIMMtristate"Support for the PAPR Storage Class Memory interface"
@@ -58,6 +58,7 @@ static int create_plpks_dir(void){structdentry*config_dir;structdentry*fdentry;+intrc;if(!IS_ENABLED(CONFIG_PSERIES_PLPKS)||!plpks_is_available()){pr_warn("Platform KeyStore is not available on this LPAR\n");
@@ -107,6 +108,13 @@ static int create_plpks_dir(void)if(IS_ERR(fdentry))pr_err("Could not create version %ld\n",PTR_ERR(fdentry));+if(IS_ENABLED(CONFIG_PSERIES_PLPKS_SECVARS)){+rc=plpks_secvars_init(plpks_dir);+if(rc)+pr_err("Secure Variables initialization failed with error %d\n",rc);+returnrc;+}+return0;}
@@ -0,0 +1,365 @@+// SPDX-License-Identifier: GPL-2.0-only+/*+*Exposesecure(authenticated)variablesforuserkeymanagement.+*Copyright(C)2022IBMCorporation+*Author:NaynaJain<nayna@linux.ibm.com>+*+*/++#include<linux/fwsecurityfs.h>+#include"plpks.h"++staticstructdentry*secvar_dir;++staticconstchar*constnames[]={+"PK",+"KEK",+"db",+"dbx",+"grubdb",+"sbat",+"moduledb",+"trustedcadb",+NULL+};++staticu16get_ucs2name(constchar*name,uint8_t**ucs2_name)+{+inti=0;+intj=0;+intnamelen=0;++namelen=strlen(name)*2;++*ucs2_name=kzalloc(namelen,GFP_KERNEL);+if(!*ucs2_name)+return0;++while(name[i]){+(*ucs2_name)[j++]=name[i];+(*ucs2_name)[j++]='\0';+pr_debug("ucs2name is %c\n",(*ucs2_name)[j-2]);+i++;+}++returnnamelen;+}++staticintvalidate_name(constchar*name)+{+inti=0;++while(names[i]){+if((strcmp(name,names[i])==0))+return0;+i++;+}+pr_err("Invalid name, allowed ones are (PK,KEK,db,dbx,grubdb,sbat,moduledb,trustedcadb)\n");++return-EINVAL;+}++staticu32get_policy(constchar*name)+{+if((strcmp(name,"db")==0)||+(strcmp(name,"dbx")==0)||+(strcmp(name,"grubdb")==0)||+(strcmp(name,"sbat")==0))+return(WORLDREADABLE|SIGNEDUPDATE);+else+returnSIGNEDUPDATE;+}++staticssize_tplpks_secvar_file_write(structfile*file,+constchar__user*userbuf,+size_tcount,loff_t*ppos)+{+structplpks_varvar;+void*data;+u16ucs2_namelen;+u8*ucs2_name=NULL;+u64flags;+ssize_trc;+boolexist=true;+u16datasize=count;+structinode*inode=file->f_mapping->host;++if(count<=sizeof(flags))+return-EINVAL;++ucs2_namelen=get_ucs2name(file_dentry(file)->d_iname,&ucs2_name);+if(ucs2_namelen==0)+return-ENOMEM;++rc=copy_from_user(&flags,userbuf,sizeof(flags));+if(rc)+return-EFAULT;++datasize=count-sizeof(flags);++data=memdup_user(userbuf+sizeof(flags),datasize);+if(IS_ERR(data))+returnPTR_ERR(data);++var.component=NULL;+var.name=ucs2_name;+var.namelen=ucs2_namelen;+var.os=PLPKS_VAR_LINUX;+var.datalen=0;+var.data=NULL;++/* If PKS variable doesn't exist, it implies first time creation */+rc=plpks_read_os_var(&var);+if(rc){+if(rc==-ENOENT){+exist=false;+}else{+pr_err("Reading variable %s failed with error %ld\n",+file_dentry(file)->d_iname,rc);+gotoout;+}+}++var.datalen=datasize;+var.data=data;+var.policy=get_policy(file_dentry(file)->d_iname);+rc=plpks_signed_update_var(var,flags);+if(rc){+pr_err("Update of the variable %s failed with error %ld\n",+file_dentry(file)->d_iname,rc);+if(!exist)+fwsecurityfs_remove_file(file_dentry(file));+gotoout;+}++/* Read variable again to get updated size of the object */+var.datalen=0;+var.data=NULL;+rc=plpks_read_os_var(&var);+if(rc)+pr_err("Error updating file size\n");++inode_lock(inode);+i_size_write(inode,var.datalen);+inode->i_mtime=current_time(inode);+inode_unlock(inode);++rc=count;+out:+kfree(data);+kfree(ucs2_name);++returnrc;+}++staticssize_t__secvar_os_file_read(char*name,char**out,u32*outlen)+{+structplpks_varvar;+intrc;+u8*ucs2_name=NULL;+u16ucs2_namelen;++ucs2_namelen=get_ucs2name(name,&ucs2_name);+if(ucs2_namelen==0)+return-ENOMEM;++var.component=NULL;+var.name=ucs2_name;+var.namelen=ucs2_namelen;+var.os=PLPKS_VAR_LINUX;+var.datalen=0;+var.data=NULL;+rc=plpks_read_os_var(&var);+if(rc){+pr_err("Error %d reading object %s from firmware\n",rc,name);+kfree(ucs2_name);+returnrc;+}++*outlen=sizeof(var.policy)+var.datalen;+*out=kzalloc(*outlen,GFP_KERNEL);+if(!*out){+rc=-ENOMEM;+gotoerr;+}++memcpy(*out,&var.policy,sizeof(var.policy));++memcpy(*out+sizeof(var.policy),var.data,var.datalen);++err:+kfree(ucs2_name);+kfree(var.data);+returnrc;+}++staticssize_t__secvar_fw_file_read(char*name,char**out,u32*outlen)+{+structplpks_varvar;+intrc;++var.component=NULL;+var.name=name;+var.namelen=strlen(name);+var.datalen=0;+var.data=NULL;+rc=plpks_read_fw_var(&var);+if(rc){+if(rc==-ENOENT){+var.datalen=1;+var.data=kzalloc(var.datalen,GFP_KERNEL);+rc=0;+}else{+pr_err("Error %d reading object %s from firmware\n",+rc,name);+returnrc;+}+}++*outlen=var.datalen;+*out=kzalloc(*outlen,GFP_KERNEL);+if(!*out){+kfree(var.data);+return-ENOMEM;+}++memcpy(*out,var.data,var.datalen);++kfree(var.data);+return0;+}++staticssize_tplpks_secvar_file_read(structfile*file,char__user*userbuf,+size_tcount,loff_t*ppos)+{+intrc;+char*out=NULL;+u32outlen;+char*fname=file_dentry(file)->d_iname;++if(strcmp(fname,"SB_VERSION")==0)+rc=__secvar_fw_file_read(fname,&out,&outlen);+else+rc=__secvar_os_file_read(fname,&out,&outlen);+if(!rc)+rc=simple_read_from_buffer(userbuf,count,ppos,+out,outlen);++kfree(out);++returnrc;+}++staticconststructfile_operationsplpks_secvar_file_operations={+.open=simple_open,+.read=plpks_secvar_file_read,+.write=plpks_secvar_file_write,+.llseek=no_llseek,+};++staticintplpks_secvar_create(structuser_namespace*mnt_userns,+structinode*dir,structdentry*dentry,+umode_tmode,boolexcl)+{+constchar*varname;+structdentry*ldentry;+intrc;++varname=dentry->d_name.name;++rc=validate_name(varname);+if(rc)+gotoout;++ldentry=fwsecurityfs_create_file(varname,S_IFREG|0644,0,+secvar_dir,dentry,NULL,+&plpks_secvar_file_operations);+if(IS_ERR(ldentry)){+rc=PTR_ERR(ldentry);+pr_err("Creation of variable %s failed with error %d\n",+varname,rc);+}++out:+returnrc;+}++staticconststructinode_operationsplpks_secvar_dir_inode_operations={+.lookup=simple_lookup,+.create=plpks_secvar_create,+};++staticintplpks_fill_secvars(void)+{+structplpks_varvar;+intrc=0;+inti=0;+u8*ucs2_name=NULL;+u16ucs2_namelen;+structdentry*dentry;++dentry=fwsecurityfs_create_file("SB_VERSION",S_IFREG|0444,1,+secvar_dir,NULL,NULL,+&plpks_secvar_file_operations);+if(IS_ERR(dentry)){+rc=PTR_ERR(dentry);+pr_err("Creation of variable SB_VERSION failed with error %d\n",rc);+returnrc;+}++while(names[i]){+ucs2_namelen=get_ucs2name(names[i],&ucs2_name);+if(ucs2_namelen==0){+i++;+continue;+}++i++;+var.component=NULL;+var.name=ucs2_name;+var.namelen=ucs2_namelen;+var.os=PLPKS_VAR_LINUX;+var.datalen=0;+var.data=NULL;+rc=plpks_read_os_var(&var);+kfree(ucs2_name);+if(rc){+rc=0;+continue;+}++dentry=fwsecurityfs_create_file(names[i-1],S_IFREG|0644,+var.datalen,secvar_dir,+NULL,NULL,+&plpks_secvar_file_operations);++kfree(var.data);+if(IS_ERR(dentry)){+rc=PTR_ERR(dentry);+pr_err("Creation of variable %s failed with error %d\n",+names[i-1],rc);+break;+}+}++returnrc;+};++intplpks_secvars_init(structdentry*parent)+{+intrc;++secvar_dir=fwsecurityfs_create_dir("secvars",S_IFDIR|0755,parent,+&plpks_secvar_dir_inode_operations);+if(IS_ERR(secvar_dir)){+rc=PTR_ERR(secvar_dir);+pr_err("Unable to create secvars dir: %d\n",rc);+returnrc;+}++rc=plpks_fill_secvars();+if(rc)+pr_err("Filling secvars failed %d\n",rc);++returnrc;+};
@@ -162,6 +162,16 @@ config PSERIES_PLPKSIfunsure,selectN.+configPSERIES_FWSECURITYFS_ARCH+selectFWSECURITYFS+bool"Support fwsecurityfs for pseries"+help+Enablefwsecurityfsarchspecificcode.Thiswouldinitialize+thefirmwaresecurityfilesystemwithinitialplatformspecific+structure.++Ifyouareunsurehowtouseit,sayN.+configPAPR_SCMdepends onPPC_PSERIES&&MEMORY_HOTPLUG&&LIBNVDIMMtristate"Support for the PAPR Storage Class Memory interface"
@@ -0,0 +1,116 @@+// SPDX-License-Identifier: GPL-2.0-only+/*+*InitializefwsecurityfswithPOWERLPARPlatformKeyStore(PLPKS)+*Copyright(C)2022IBMCorporation+*Author:NaynaJain<nayna@linux.ibm.com>+*+*/++#include<linux/fwsecurityfs.h>+#include"plpks.h"++staticstructdentry*plpks_dir;++staticssize_tplpks_config_file_read(structfile*file,char__user*userbuf,+size_tcount,loff_t*ppos)+{+u8out[4];+u32outlen;+size_tsize;+char*name;+u32data;++name=file_dentry(file)->d_iname;++if(strcmp(name,"max_object_size")==0){+outlen=sizeof(u16);+data=plpks_get_maxobjectsize();+}elseif(strcmp(name,"max_object_label_size")==0){+outlen=sizeof(u16);+data=plpks_get_maxobjectlabelsize();+}elseif(strcmp(name,"total_size")==0){+outlen=sizeof(u32);+data=plpks_get_totalsize();+}elseif(strcmp(name,"used_space")==0){+outlen=sizeof(u32);+data=plpks_get_usedspace();+}elseif(strcmp(name,"version")==0){+outlen=sizeof(u8);+data=plpks_get_version();+}else{+return-EINVAL;+}++memcpy(out,&data,outlen);++size=simple_read_from_buffer(userbuf,count,ppos,out,outlen);++returnsize;+}++staticconststructfile_operationsplpks_config_file_operations={+.open=simple_open,+.read=plpks_config_file_read,+.llseek=no_llseek,+};++staticintcreate_plpks_dir(void)+{+structdentry*config_dir;+structdentry*fdentry;++if(!IS_ENABLED(CONFIG_PSERIES_PLPKS)||!plpks_is_available()){+pr_warn("Platform KeyStore is not available on this LPAR\n");+return0;+}++plpks_dir=fwsecurityfs_create_dir("plpks",S_IFDIR|0755,NULL,+NULL);+if(IS_ERR(plpks_dir)){+pr_err("Unable to create PLPKS dir: %ld\n",PTR_ERR(plpks_dir));+returnPTR_ERR(plpks_dir);+}++config_dir=fwsecurityfs_create_dir("config",S_IFDIR|0755,plpks_dir,NULL);+if(IS_ERR(config_dir)){+pr_err("Unable to create config dir: %ld\n",PTR_ERR(config_dir));+returnPTR_ERR(config_dir);+}++fdentry=fwsecurityfs_create_file("max_object_size",S_IFREG|0444,+sizeof(u16),config_dir,NULL,NULL,+&plpks_config_file_operations);+if(IS_ERR(fdentry))+pr_err("Could not create max object size %ld\n",PTR_ERR(fdentry));++fdentry=fwsecurityfs_create_file("max_object_label_size",S_IFREG|0444,+sizeof(u16),config_dir,NULL,NULL,+&plpks_config_file_operations);+if(IS_ERR(fdentry))+pr_err("Could not create max object label size %ld\n",PTR_ERR(fdentry));++fdentry=fwsecurityfs_create_file("total_size",S_IFREG|0444,+sizeof(u32),config_dir,NULL,NULL,+&plpks_config_file_operations);+if(IS_ERR(fdentry))+pr_err("Could not create total size %ld\n",PTR_ERR(fdentry));++fdentry=fwsecurityfs_create_file("used_space",S_IFREG|0444,+sizeof(u32),config_dir,NULL,NULL,+&plpks_config_file_operations);+if(IS_ERR(fdentry))+pr_err("Could not create used space %ld\n",PTR_ERR(fdentry));++fdentry=fwsecurityfs_create_file("version",S_IFREG|0444,+sizeof(u8),config_dir,NULL,NULL,+&plpks_config_file_operations);+if(IS_ERR(fdentry))+pr_err("Could not create version %ld\n",PTR_ERR(fdentry));++return0;+}++intarch_fwsecurityfs_init(void)+{+returncreate_plpks_dir();+}
fs/fwsecurityfs/super.c:248:39: error: 'firmware_kobj' undeclared (first use in this function)
248 | rc = sysfs_create_mount_point(firmware_kobj, "security");
| ^~~~~~~~~~~~~
fs/fwsecurityfs/super.c:248:39: note: each undeclared identifier is reported only once for each function it appears in
quoted
fs/fwsecurityfs/super.c:254:17: error: implicit declaration of function 'sysfs_remove_mount_point' [-Werror=implicit-function-declaration]
254 | sysfs_remove_mount_point(firmware_kobj, "security");
| ^~~~~~~~~~~~~~~~~~~~~~~~
fs/fwsecurityfs/super.c: At top level:
quoted
fs/fwsecurityfs/super.c:261:20: error: expected declaration specifiers or '...' before string constant
261 | MODULE_DESCRIPTION("Firmware Security Filesystem");
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
fs/fwsecurityfs/super.c:262:15: error: expected declaration specifiers or '...' before string constant
262 | MODULE_AUTHOR("Nayna Jain");
| ^~~~~~~~~~~~
fs/fwsecurityfs/super.c:263:16: error: expected declaration specifiers or '...' before string constant
263 | MODULE_LICENSE("GPL");
| ^~~~~
cc1: some warnings being treated as errors
vim +/sysfs_create_mount_point +248 fs/fwsecurityfs/super.c
243
244 static int __init fwsecurityfs_init(void)
245 {
246 int rc;
247
> 248 rc = sysfs_create_mount_point(firmware_kobj, "security");
249 if (rc)
250 return rc;
251
252 rc = register_filesystem(&fs_type);
253 if (rc) {
> 254 sysfs_remove_mount_point(firmware_kobj, "security");
255 return rc;
256 }
257
258 return 0;
259 }
260 core_initcall(fwsecurityfs_init);
> 261 MODULE_DESCRIPTION("Firmware Security Filesystem");
--
0-DAY CI Kernel Test Service
https://01.org/lkp
On Sun, Nov 06, 2022 at 04:07:42PM -0500, Nayna Jain wrote:
securityfs is meant for Linux security subsystems to expose policies/logs
or any other information. However, there are various firmware security
features which expose their variables for user management via the kernel.
There is currently no single place to expose these variables. Different
platforms use sysfs/platform specific filesystem(efivarfs)/securityfs
interface as they find it appropriate. Thus, there is a gap in kernel
interfaces to expose variables for security features.
Define a firmware security filesystem (fwsecurityfs) to be used by
security features enabled by the firmware. These variables are platform
specific. This filesystem provides platforms a way to implement their
own underlying semantics by defining own inode and file operations.
Similar to securityfs, the firmware security filesystem is recommended
to be exposed on a well known mount point /sys/firmware/security.
Platforms can define their own directory or file structure under this path.
Example:
# mount -t fwsecurityfs fwsecurityfs /sys/firmware/security
Why not juset use securityfs in /sys/security/firmware/ instead? Then
you don't have to create a new filesystem and convince userspace to
mount it in a specific location?
thanks,
greg k-h
On Sun, Nov 06, 2022 at 04:07:42PM -0500, Nayna Jain wrote:
quoted
securityfs is meant for Linux security subsystems to expose policies/logs
or any other information. However, there are various firmware security
features which expose their variables for user management via the kernel.
There is currently no single place to expose these variables. Different
platforms use sysfs/platform specific filesystem(efivarfs)/securityfs
interface as they find it appropriate. Thus, there is a gap in kernel
interfaces to expose variables for security features.
Define a firmware security filesystem (fwsecurityfs) to be used by
security features enabled by the firmware. These variables are platform
specific. This filesystem provides platforms a way to implement their
own underlying semantics by defining own inode and file operations.
Similar to securityfs, the firmware security filesystem is recommended
to be exposed on a well known mount point /sys/firmware/security.
Platforms can define their own directory or file structure under this path.
Example:
# mount -t fwsecurityfs fwsecurityfs /sys/firmware/security
Why not juset use securityfs in /sys/security/firmware/ instead? Then
you don't have to create a new filesystem and convince userspace to
mount it in a specific location?
From man 5 sysfs page:
/sys/firmware: This subdirectory contains interfaces for viewing and
manipulating firmware-specific objects and attributes.
/sys/kernel: This subdirectory contains various files and subdirectories
that provide information about the running kernel.
The security variables which are being exposed via fwsecurityfs are
managed by firmware, stored in firmware managed space and also often
consumed by firmware for enabling various security features.
From git commit b67dbf9d4c1987c370fd18fdc4cf9d8aaea604c2, the purpose
of securityfs(/sys/kernel/security) is to provide a common place for all
kernel LSMs. The idea of
fwsecurityfs(/sys/firmware/security) is to similarly provide a common
place for all firmware security objects.
/sys/firmware already exists. The patch now defines a new /security
directory in it for firmware security features. Using
/sys/kernel/security would mean scattering firmware objects in multiple
places and confusing the purpose of /sys/kernel and /sys/firmware.
Even though fwsecurityfs code is based on securityfs, since the two
filesystems expose different types of objects and have different
requirements, there are distinctions:
1. fwsecurityfs lets users create files in userspace, securityfs only
allows kernel subsystems to create files.
2. firmware and kernel objects may have different requirements. For
example, consideration of namespacing. As per my understanding,
namespacing is applied to kernel resources and not firmware resources.
That's why it makes sense to add support for namespacing in securityfs,
but we concluded that fwsecurityfs currently doesn't need it. Another
but similar example of it is: TPM space, which is exposed from hardware.
For containers, the TPM would be made as virtual/software TPM. Similarly
for firmware space for containers, it would have to be something
virtualized/software version of it.
3. firmware objects are persistent and read at boot time by interaction
with firmware, unlike kernel objects which are not persistent.
For a more detailed explanation refer to the LSS-NA 2022 "PowerVM
Platform Keystore - Securing Linux Credentials Locally" talk and
slides[1]. The link to previously posted RFC version is [2].
[1]
https://static.sched.com/hosted_files/lssna2022/25/NaynaJain_PowerVM_PlatformKeyStore_SecuringLinuxCredentialsLocally.pdf
[2] https://lore.kernel.org/linuxppc-dev/YrQqPhi4+jHZ1WJc@kroah.com/
Thanks & Regards,
- Nayna
On Wed, Nov 09, 2022 at 03:10:37PM -0500, Nayna wrote:
On 11/9/22 08:46, Greg Kroah-Hartman wrote:
quoted
On Sun, Nov 06, 2022 at 04:07:42PM -0500, Nayna Jain wrote:
quoted
securityfs is meant for Linux security subsystems to expose policies/logs
or any other information. However, there are various firmware security
features which expose their variables for user management via the kernel.
There is currently no single place to expose these variables. Different
platforms use sysfs/platform specific filesystem(efivarfs)/securityfs
interface as they find it appropriate. Thus, there is a gap in kernel
interfaces to expose variables for security features.
Define a firmware security filesystem (fwsecurityfs) to be used by
security features enabled by the firmware. These variables are platform
specific. This filesystem provides platforms a way to implement their
own underlying semantics by defining own inode and file operations.
Similar to securityfs, the firmware security filesystem is recommended
to be exposed on a well known mount point /sys/firmware/security.
Platforms can define their own directory or file structure under this path.
Example:
# mount -t fwsecurityfs fwsecurityfs /sys/firmware/security
Why not juset use securityfs in /sys/security/firmware/ instead? Then
you don't have to create a new filesystem and convince userspace to
mount it in a specific location?
From man 5 sysfs page:
/sys/firmware: This subdirectory contains interfaces for viewing and
manipulating firmware-specific objects and attributes.
/sys/kernel: This subdirectory contains various files and subdirectories
that provide information about the running kernel.
The security variables which are being exposed via fwsecurityfs are managed
by firmware, stored in firmware managed space and also often consumed by
firmware for enabling various security features.
Ok, then just use the normal sysfs interface for /sys/firmware, why do
you need a whole new filesystem type?
From git commit b67dbf9d4c1987c370fd18fdc4cf9d8aaea604c2, the purpose of
securityfs(/sys/kernel/security) is to provide a common place for all kernel
LSMs. The idea of
fwsecurityfs(/sys/firmware/security) is to similarly provide a common place
for all firmware security objects.
/sys/firmware already exists. The patch now defines a new /security
directory in it for firmware security features. Using /sys/kernel/security
would mean scattering firmware objects in multiple places and confusing the
purpose of /sys/kernel and /sys/firmware.
sysfs is confusing already, no problem with making it more confusing :)
Just document where you add things and all should be fine.
Even though fwsecurityfs code is based on securityfs, since the two
filesystems expose different types of objects and have different
requirements, there are distinctions:
1. fwsecurityfs lets users create files in userspace, securityfs only allows
kernel subsystems to create files.
Wait, why would a user ever create a file in this filesystem? If you
need that, why not use configfs? That's what that is for, right?
2. firmware and kernel objects may have different requirements. For example,
consideration of namespacing. As per my understanding, namespacing is
applied to kernel resources and not firmware resources. That's why it makes
sense to add support for namespacing in securityfs, but we concluded that
fwsecurityfs currently doesn't need it. Another but similar example of it
is: TPM space, which is exposed from hardware. For containers, the TPM would
be made as virtual/software TPM. Similarly for firmware space for
containers, it would have to be something virtualized/software version of
it.
I do not understand, sorry. What does namespaces have to do with this?
sysfs can already handle namespaces just fine, why not use that?
3. firmware objects are persistent and read at boot time by interaction with
firmware, unlike kernel objects which are not persistent.
That doesn't matter, sysfs exports what the hardware provides, and that
might persist over boot.
So I don't see why a new filesystem is needed.
You didn't explain why sysfs, or securitfs (except for the location in
the tree) does not work at all for your needs. The location really
doesn't matter all that much as you are creating a brand new location
anyway so we can just declare "this is where this stuff goes" and be ok.
And again, how are you going to get all Linux distros to now mount your
new filesystem?
thanks,
greg k-h
On Wed, Nov 09, 2022 at 03:10:37PM -0500, Nayna wrote:
quoted
On 11/9/22 08:46, Greg Kroah-Hartman wrote:
quoted
On Sun, Nov 06, 2022 at 04:07:42PM -0500, Nayna Jain wrote:
quoted
securityfs is meant for Linux security subsystems to expose policies/logs
or any other information. However, there are various firmware security
features which expose their variables for user management via the kernel.
There is currently no single place to expose these variables. Different
platforms use sysfs/platform specific filesystem(efivarfs)/securityfs
interface as they find it appropriate. Thus, there is a gap in kernel
interfaces to expose variables for security features.
Define a firmware security filesystem (fwsecurityfs) to be used by
security features enabled by the firmware. These variables are platform
specific. This filesystem provides platforms a way to implement their
own underlying semantics by defining own inode and file operations.
Similar to securityfs, the firmware security filesystem is recommended
to be exposed on a well known mount point /sys/firmware/security.
Platforms can define their own directory or file structure under this path.
Example:
# mount -t fwsecurityfs fwsecurityfs /sys/firmware/security
Why not juset use securityfs in /sys/security/firmware/ instead? Then
you don't have to create a new filesystem and convince userspace to
mount it in a specific location?
From man 5 sysfs page:
/sys/firmware: This subdirectory contains interfaces for viewing and
manipulating firmware-specific objects and attributes.
/sys/kernel: This subdirectory contains various files and subdirectories
that provide information about the running kernel.
The security variables which are being exposed via fwsecurityfs are managed
by firmware, stored in firmware managed space and also often consumed by
firmware for enabling various security features.
Ok, then just use the normal sysfs interface for /sys/firmware, why do
you need a whole new filesystem type?
quoted
From git commit b67dbf9d4c1987c370fd18fdc4cf9d8aaea604c2, the purpose of
securityfs(/sys/kernel/security) is to provide a common place for all kernel
LSMs. The idea of
fwsecurityfs(/sys/firmware/security) is to similarly provide a common place
for all firmware security objects.
/sys/firmware already exists. The patch now defines a new /security
directory in it for firmware security features. Using /sys/kernel/security
would mean scattering firmware objects in multiple places and confusing the
purpose of /sys/kernel and /sys/firmware.
sysfs is confusing already, no problem with making it more confusing :)
Just document where you add things and all should be fine.
quoted
Even though fwsecurityfs code is based on securityfs, since the two
filesystems expose different types of objects and have different
requirements, there are distinctions:
1. fwsecurityfs lets users create files in userspace, securityfs only allows
kernel subsystems to create files.
Wait, why would a user ever create a file in this filesystem? If you
need that, why not use configfs? That's what that is for, right?
The purpose of fwsecurityfs is not to expose configuration items but
rather security objects used for firmware security features. I think
these are more comparable to EFI variables, which are exposed via an
EFI-specific filesystem, efivarfs, rather than configfs.
quoted
2. firmware and kernel objects may have different requirements. For example,
consideration of namespacing. As per my understanding, namespacing is
applied to kernel resources and not firmware resources. That's why it makes
sense to add support for namespacing in securityfs, but we concluded that
fwsecurityfs currently doesn't need it. Another but similar example of it
is: TPM space, which is exposed from hardware. For containers, the TPM would
be made as virtual/software TPM. Similarly for firmware space for
containers, it would have to be something virtualized/software version of
it.
I do not understand, sorry. What does namespaces have to do with this?
sysfs can already handle namespaces just fine, why not use that?
3. firmware objects are persistent and read at boot time by interaction with
firmware, unlike kernel objects which are not persistent.
That doesn't matter, sysfs exports what the hardware provides, and that
might persist over boot.
So I don't see why a new filesystem is needed.
You didn't explain why sysfs, or securitfs (except for the location in
the tree) does not work at all for your needs. The location really
doesn't matter all that much as you are creating a brand new location
anyway so we can just declare "this is where this stuff goes" and be ok.
For rest of the questions, here is the summarized response.
Based on mailing list previous discussions [1][2][3] and considering
various firmware security use cases, our fwsecurityfs proposal seemed to
be a reasonable and acceptable approach based on the feedback [4].
[1] https://lore.kernel.org/linuxppc-dev/YeuyUVVdFADCuDr4@kroah.com/#t
[2] https://lore.kernel.org/linuxppc-dev/Yfk6gucNmJuR%2Fegi@kroah.com/
[3]
https://lore.kernel.org/all/Yfo%2F5gYgb9Sv24YB@kroah.com/t/#m40250fdb3fddaafe502ab06e329e63381b00582d
[4] https://lore.kernel.org/linuxppc-dev/YrQqPhi4+jHZ1WJc@kroah.com/
RFC v1 was using sysfs. After considering feedback[1][2][3], the
following are design considerations for unification via fwsecurityfs:
1. Unify the location: Defining a security directory under /sys/firmware
facilitates exposing objects related to firmware security features in a
single place. Different platforms can create their respective directory
structures within /sys/firmware/security.
2. Unify the code: To support unification, having the fwsecurityfs
filesystem API allows different platforms to define the inode and file
operations they need. fwsecurityfs provides a common API that can be
used by each platform-specific implementation to support its particular
requirements and interaction with firmware. Initializing
platform-specific functions is the purpose of the
fwsecurityfs_arch_init() function that is called on mount. Patch 3/4
implements fwsecurityfs_arch_init() for powerpc.
Similar to the common place securityfs provides for LSMs to interact
with kernel security objects, fwsecurityfs would provide a common place
for all firmware security objects, which interact with the firmware
rather than the kernel. Although at the API level, the two filesystem
look similar, the requirements for firmware and kernel objects are
different. Therefore, reusing securityfs wasn't a good fit for the
firmware use case and we are proposing a similar but different
filesystem - fwsecurityfs - focused for firmware security.
And again, how are you going to get all Linux distros to now mount your
new filesystem?
It would be analogous to the way securityfs is mounted.
Thanks & Regards,
- Nayna
On Mon, Nov 14, 2022 at 06:03:43PM -0500, Nayna wrote:
On 11/10/22 04:58, Greg Kroah-Hartman wrote:
quoted
On Wed, Nov 09, 2022 at 03:10:37PM -0500, Nayna wrote:
quoted
On 11/9/22 08:46, Greg Kroah-Hartman wrote:
quoted
On Sun, Nov 06, 2022 at 04:07:42PM -0500, Nayna Jain wrote:
quoted
securityfs is meant for Linux security subsystems to expose policies/logs
or any other information. However, there are various firmware security
features which expose their variables for user management via the kernel.
There is currently no single place to expose these variables. Different
platforms use sysfs/platform specific filesystem(efivarfs)/securityfs
interface as they find it appropriate. Thus, there is a gap in kernel
interfaces to expose variables for security features.
Define a firmware security filesystem (fwsecurityfs) to be used by
security features enabled by the firmware. These variables are platform
specific. This filesystem provides platforms a way to implement their
own underlying semantics by defining own inode and file operations.
Similar to securityfs, the firmware security filesystem is recommended
to be exposed on a well known mount point /sys/firmware/security.
Platforms can define their own directory or file structure under this path.
Example:
# mount -t fwsecurityfs fwsecurityfs /sys/firmware/security
Why not juset use securityfs in /sys/security/firmware/ instead? Then
you don't have to create a new filesystem and convince userspace to
mount it in a specific location?
From man 5 sysfs page:
/sys/firmware: This subdirectory contains interfaces for viewing and
manipulating firmware-specific objects and attributes.
/sys/kernel: This subdirectory contains various files and subdirectories
that provide information about the running kernel.
The security variables which are being exposed via fwsecurityfs are managed
by firmware, stored in firmware managed space and also often consumed by
firmware for enabling various security features.
Ok, then just use the normal sysfs interface for /sys/firmware, why do
you need a whole new filesystem type?
quoted
From git commit b67dbf9d4c1987c370fd18fdc4cf9d8aaea604c2, the purpose of
securityfs(/sys/kernel/security) is to provide a common place for all kernel
LSMs. The idea of
fwsecurityfs(/sys/firmware/security) is to similarly provide a common place
for all firmware security objects.
/sys/firmware already exists. The patch now defines a new /security
directory in it for firmware security features. Using /sys/kernel/security
would mean scattering firmware objects in multiple places and confusing the
purpose of /sys/kernel and /sys/firmware.
sysfs is confusing already, no problem with making it more confusing :)
Just document where you add things and all should be fine.
quoted
Even though fwsecurityfs code is based on securityfs, since the two
filesystems expose different types of objects and have different
requirements, there are distinctions:
1. fwsecurityfs lets users create files in userspace, securityfs only allows
kernel subsystems to create files.
Wait, why would a user ever create a file in this filesystem? If you
need that, why not use configfs? That's what that is for, right?
The purpose of fwsecurityfs is not to expose configuration items but rather
security objects used for firmware security features. I think these are more
comparable to EFI variables, which are exposed via an EFI-specific
filesystem, efivarfs, rather than configfs.
quoted
quoted
2. firmware and kernel objects may have different requirements. For example,
consideration of namespacing. As per my understanding, namespacing is
applied to kernel resources and not firmware resources. That's why it makes
sense to add support for namespacing in securityfs, but we concluded that
fwsecurityfs currently doesn't need it. Another but similar example of it
is: TPM space, which is exposed from hardware. For containers, the TPM would
be made as virtual/software TPM. Similarly for firmware space for
containers, it would have to be something virtualized/software version of
it.
I do not understand, sorry. What does namespaces have to do with this?
sysfs can already handle namespaces just fine, why not use that?
I do not understand, sorry. Do you want to use a namespace for these or
not? The code does not seem to be using namespaces. You can use sysfs
with, or without, a namespace so I don't understand the issue here.
With your code, there is no namespace.
quoted
quoted
3. firmware objects are persistent and read at boot time by interaction with
firmware, unlike kernel objects which are not persistent.
That doesn't matter, sysfs exports what the hardware provides, and that
might persist over boot.
So I don't see why a new filesystem is needed.
You didn't explain why sysfs, or securitfs (except for the location in
the tree) does not work at all for your needs. The location really
doesn't matter all that much as you are creating a brand new location
anyway so we can just declare "this is where this stuff goes" and be ok.
So just pick one place in sysfs for this to always go into.
Your patch series does not document anything here, there are no
Documentation/ABI/ entries that define the files being created, so that
it's really hard to be able to review the code to determine if it is
doing what you are wanting it to do.
You can't document apis with just a changelog text alone, sorry.
2. Unify the code: To support unification, having the fwsecurityfs
filesystem API allows different platforms to define the inode and file
operations they need. fwsecurityfs provides a common API that can be used by
each platform-specific implementation to support its particular requirements
and interaction with firmware. Initializing platform-specific functions is
the purpose of the fwsecurityfs_arch_init() function that is called on
mount. Patch 3/4 implements fwsecurityfs_arch_init() for powerpc.
But you only are doing this for one platform, that's not any
unification. APIs don't really work unless they can handle 3 users, as
then you really understand if they work or not.
Right now you wrote this code and it only has one user, that's a
platform-specific-filesystem-only so far.
Similar to the common place securityfs provides for LSMs to interact with
kernel security objects, fwsecurityfs would provide a common place for all
firmware security objects, which interact with the firmware rather than the
kernel. Although at the API level, the two filesystem look similar, the
requirements for firmware and kernel objects are different. Therefore,
reusing securityfs wasn't a good fit for the firmware use case and we are
proposing a similar but different filesystem - fwsecurityfs - focused for
firmware security.
What other platforms will use this? Who is going to move their code
over to it?
quoted
And again, how are you going to get all Linux distros to now mount your
new filesystem?
It would be analogous to the way securityfs is mounted.
That did not answer the question. The question is how are you going to
get the distros to mount your new filesystem specifically? How will
they know that they need to modify their init scripts to do this? Who
is going to do that? For what distro? On what timeline?
Oh, and it looks like this series doesn't pass the kernel testing bot at
all, so I'll not review the code until that's all fixed up at the very
least.
thanks,
greg k-h
On Mon, Nov 14, 2022 at 06:03:43PM -0500, Nayna wrote:
quoted
On 11/10/22 04:58, Greg Kroah-Hartman wrote:
quoted
On Wed, Nov 09, 2022 at 03:10:37PM -0500, Nayna wrote:
quoted
On 11/9/22 08:46, Greg Kroah-Hartman wrote:
quoted
On Sun, Nov 06, 2022 at 04:07:42PM -0500, Nayna Jain wrote:
quoted
securityfs is meant for Linux security subsystems to expose policies/logs
or any other information. However, there are various firmware security
features which expose their variables for user management via the kernel.
There is currently no single place to expose these variables. Different
platforms use sysfs/platform specific filesystem(efivarfs)/securityfs
interface as they find it appropriate. Thus, there is a gap in kernel
interfaces to expose variables for security features.
Define a firmware security filesystem (fwsecurityfs) to be used by
security features enabled by the firmware. These variables are platform
specific. This filesystem provides platforms a way to implement their
own underlying semantics by defining own inode and file operations.
Similar to securityfs, the firmware security filesystem is recommended
to be exposed on a well known mount point /sys/firmware/security.
Platforms can define their own directory or file structure under this path.
Example:
# mount -t fwsecurityfs fwsecurityfs /sys/firmware/security
Why not juset use securityfs in /sys/security/firmware/ instead? Then
you don't have to create a new filesystem and convince userspace to
mount it in a specific location?
From man 5 sysfs page:
/sys/firmware: This subdirectory contains interfaces for viewing and
manipulating firmware-specific objects and attributes.
/sys/kernel: This subdirectory contains various files and subdirectories
that provide information about the running kernel.
The security variables which are being exposed via fwsecurityfs are managed
by firmware, stored in firmware managed space and also often consumed by
firmware for enabling various security features.
Ok, then just use the normal sysfs interface for /sys/firmware, why do
you need a whole new filesystem type?
quoted
From git commit b67dbf9d4c1987c370fd18fdc4cf9d8aaea604c2, the purpose of
securityfs(/sys/kernel/security) is to provide a common place for all kernel
LSMs. The idea of
fwsecurityfs(/sys/firmware/security) is to similarly provide a common place
for all firmware security objects.
/sys/firmware already exists. The patch now defines a new /security
directory in it for firmware security features. Using /sys/kernel/security
would mean scattering firmware objects in multiple places and confusing the
purpose of /sys/kernel and /sys/firmware.
sysfs is confusing already, no problem with making it more confusing :)
Just document where you add things and all should be fine.
quoted
Even though fwsecurityfs code is based on securityfs, since the two
filesystems expose different types of objects and have different
requirements, there are distinctions:
1. fwsecurityfs lets users create files in userspace, securityfs only allows
kernel subsystems to create files.
Wait, why would a user ever create a file in this filesystem? If you
need that, why not use configfs? That's what that is for, right?
The purpose of fwsecurityfs is not to expose configuration items but rather
security objects used for firmware security features. I think these are more
comparable to EFI variables, which are exposed via an EFI-specific
filesystem, efivarfs, rather than configfs.
quoted
quoted
2. firmware and kernel objects may have different requirements. For example,
consideration of namespacing. As per my understanding, namespacing is
applied to kernel resources and not firmware resources. That's why it makes
sense to add support for namespacing in securityfs, but we concluded that
fwsecurityfs currently doesn't need it. Another but similar example of it
is: TPM space, which is exposed from hardware. For containers, the TPM would
be made as virtual/software TPM. Similarly for firmware space for
containers, it would have to be something virtualized/software version of
it.
I do not understand, sorry. What does namespaces have to do with this?
sysfs can already handle namespaces just fine, why not use that?
I do not understand, sorry. Do you want to use a namespace for these or
not? The code does not seem to be using namespaces. You can use sysfs
with, or without, a namespace so I don't understand the issue here.
With your code, there is no namespace.
You are correct. There's no namespace for these.
quoted
quoted
quoted
3. firmware objects are persistent and read at boot time by interaction with
firmware, unlike kernel objects which are not persistent.
That doesn't matter, sysfs exports what the hardware provides, and that
might persist over boot.
So I don't see why a new filesystem is needed.
You didn't explain why sysfs, or securitfs (except for the location in
the tree) does not work at all for your needs. The location really
doesn't matter all that much as you are creating a brand new location
anyway so we can just declare "this is where this stuff goes" and be ok.
So just pick one place in sysfs for this to always go into.
I agree that the objects should go directly under a
/sys/firmware/security mountpoint.
Your patch series does not document anything here, there are no
Documentation/ABI/ entries that define the files being created, so that
it's really hard to be able to review the code to determine if it is
doing what you are wanting it to do.
You can't document apis with just a changelog text alone, sorry.
Agreed, I'll include documentation in the next version.
quoted
2. Unify the code: To support unification, having the fwsecurityfs
filesystem API allows different platforms to define the inode and file
operations they need. fwsecurityfs provides a common API that can be used by
each platform-specific implementation to support its particular requirements
and interaction with firmware. Initializing platform-specific functions is
the purpose of the fwsecurityfs_arch_init() function that is called on
mount. Patch 3/4 implements fwsecurityfs_arch_init() for powerpc.
But you only are doing this for one platform, that's not any
unification. APIs don't really work unless they can handle 3 users, as
then you really understand if they work or not.
Right now you wrote this code and it only has one user, that's a
platform-specific-filesystem-only so far.
Yes I agree, having more exploiters would certainly help to confirm and
improve the interface.
If you prefer, we could start with an arch specific filesystem. It could
be made generic in the future if required.
quoted
Similar to the common place securityfs provides for LSMs to interact with
kernel security objects, fwsecurityfs would provide a common place for all
firmware security objects, which interact with the firmware rather than the
kernel. Although at the API level, the two filesystem look similar, the
requirements for firmware and kernel objects are different. Therefore,
reusing securityfs wasn't a good fit for the firmware use case and we are
proposing a similar but different filesystem - fwsecurityfs - focused for
firmware security.
What other platforms will use this? Who is going to move their code
over to it?
I had received constructive feedback on my RFC v2 but thus far, no other
platforms have indicated they have a need for it.
quoted
quoted
And again, how are you going to get all Linux distros to now mount your
new filesystem?
It would be analogous to the way securityfs is mounted.
That did not answer the question. The question is how are you going to
get the distros to mount your new filesystem specifically? How will
they know that they need to modify their init scripts to do this? Who
is going to do that? For what distro? On what timeline?
I'll add a documentation patch for fwsecurityfs. And I'll propose a
systemd patch to extend mount_table[] in src/shared/mount-setup.c to
include fwsecurityfs.
For RHEL 9.3 and SLES 15 SP6, we have feature requests opened to request
adoption of the PKS userspace interface. We will communicate the mount
point and init script changes via those feature requests.
Other distros can adapt the upstream implementation to fit their
requirements, such as mounting via simple init scripts without systemd
for more constrained systems, using the systemd as an example.
Please let me know if you have other concerns with respect to mounting
the filesystem.
Oh, and it looks like this series doesn't pass the kernel testing bot at
all, so I'll not review the code until that's all fixed up at the very
least.
I knew it failed, but I wanted to get your feedback on the approach
before posting a new version. I'll fix it.
Thank you for your review and feedback. I hope I have addressed your
concerns.
Thanks & Regards,
- Nayna
On Sun, Nov 06, 2022 at 04:07:42PM -0500, Nayna Jain wrote:
quoted
securityfs is meant for Linux security subsystems to expose policies/logs
or any other information. However, there are various firmware security
features which expose their variables for user management via the kernel.
There is currently no single place to expose these variables. Different
platforms use sysfs/platform specific filesystem(efivarfs)/securityfs
interface as they find it appropriate. Thus, there is a gap in kernel
interfaces to expose variables for security features.
Define a firmware security filesystem (fwsecurityfs) to be used by
security features enabled by the firmware. These variables are platform
specific. This filesystem provides platforms a way to implement their
own underlying semantics by defining own inode and file operations.
Similar to securityfs, the firmware security filesystem is recommended
to be exposed on a well known mount point /sys/firmware/security.
Platforms can define their own directory or file structure under this path.
Example:
# mount -t fwsecurityfs fwsecurityfs /sys/firmware/security
Why not juset use securityfs in /sys/security/firmware/ instead? Then
you don't have to create a new filesystem and convince userspace to
mount it in a specific location?
I am also curious to know on why not use securityfs, given the similarity
between the two. :)
More specifics on that below...
From man 5 sysfs page:
/sys/firmware: This subdirectory contains interfaces for viewing and
manipulating firmware-specific objects and attributes.
/sys/kernel: This subdirectory contains various files and subdirectories
that provide information about the running kernel.
The security variables which are being exposed via fwsecurityfs are managed
by firmware, stored in firmware managed space and also often consumed by
firmware for enabling various security features.
That's ok. As I see it users of securityfs can define their own fileops
(like how you are doing in fwsecurityfs).
See securityfs_create_file() & securityfs_create_symlink(), can accept the fops
& iops. Except maybe securityfs_create_dir(), that could be since there might
not be a usecase for it. But do you also need it in your case is the question to
ask.
From git commit b67dbf9d4c1987c370fd18fdc4cf9d8aaea604c2, the purpose of
securityfs(/sys/kernel/security) is to provide a common place for all kernel
LSMs. The idea of
Which was then seperated out by commit,
da31894ed7b654e2 ("securityfs: do not depend on CONFIG_SECURITY").
securityfs now has a seperate CONFIG_SECURITYFS config option. In fact I was even
thinking of why shouldn't we move security/inode.c into fs/securityfs/inode.c .
fs/* is a common place for all filesystems. Users of securityfs can call it's
exported kernel APIs to create files/dirs/symlinks.
If we move security/inode.c to fs/security/inode.c, then...
...below call within securityfs_init() should be moved into some lsm sepecific
file.
#ifdef CONFIG_SECURITY
static struct dentry *lsm_dentry;
static ssize_t lsm_read(struct file *filp, char __user *buf, size_t count,
loff_t *ppos)
{
return simple_read_from_buffer(buf, count, ppos, lsm_names,
strlen(lsm_names));
}
static const struct file_operations lsm_ops = {
.read = lsm_read,
.llseek = generic_file_llseek,
};
#endif
securityfs_init()
#ifdef CONFIG_SECURITY
lsm_dentry = securityfs_create_file("lsm", 0444, NULL, NULL,
&lsm_ops);
#endif
So why not move it? Maybe others, can comment more on whether it's a good idea
to move security/inode.c into fs/security/inode.c?
This should then help others identify securityfs filesystem in fs/security/
for everyone to notice and utilize for their use?
fwsecurityfs(/sys/firmware/security) is to similarly provide a common place
for all firmware security objects.
/sys/firmware already exists. The patch now defines a new /security
directory in it for firmware security features. Using /sys/kernel/security
would mean scattering firmware objects in multiple places and confusing the
purpose of /sys/kernel and /sys/firmware.
We can also think of it this way that, all security related exports should
happen via /sys/kernel/security/. Then /sys/kernel/security/firmware/ becomes
the security related firmware exports.
If you see find /sys -iname firmware, I am sure you will find other firmware
specifics directories related to other specific subsystems
(e.g.
root@qemu:/home/qemu# find /sys -iname firmware
/sys/devices/ndbus0/nmem0/firmware
/sys/devices/ndbus0/firmware
/sys/firmware
)
But it could be, I am not an expert here, although I was thinking a good
Documentation might solve this problem.
Even though fwsecurityfs code is based on securityfs, since the two
filesystems expose different types of objects and have different
requirements, there are distinctions:
1. fwsecurityfs lets users create files in userspace, securityfs only allows
kernel subsystems to create files.
Sorry could you please elaborate how? both securityfs & fwsecurityfs
calls simple_fill_super() which uses the same inode (i_op) and inode file
operations (i_fop) from fs/libfs.c for their root inode. So how it is enabling
user (as in userspace) to create a file in this filesystem?
So am I missing anything?
2. firmware and kernel objects may have different requirements. For example,
consideration of namespacing. As per my understanding, namespacing is
applied to kernel resources and not firmware resources. That's why it makes
sense to add support for namespacing in securityfs, but we concluded that
fwsecurityfs currently doesn't need it. Another but similar example of it
It "currently" doesn't need it. But can it in future? Then why not go with
securityfs which has an additional namespacing feature available?
That's actually also the point of utilizing an existing FS which can get
features like this in future. As long as it doesn't affect the functionality
of your use case, we simply need not reject securityfs, no?
is: TPM space, which is exposed from hardware. For containers, the TPM would
be made as virtual/software TPM. Similarly for firmware space for
containers, it would have to be something virtualized/software version of
it.
3. firmware objects are persistent and read at boot time by interaction with
firmware, unlike kernel objects which are not persistent.
I think this got addressed in a seperate thread.
-ritesh
On Sat, Nov 19, 2022 at 01:20:09AM -0500, Nayna wrote:
On 11/17/22 16:27, Greg Kroah-Hartman wrote:
quoted
On Mon, Nov 14, 2022 at 06:03:43PM -0500, Nayna wrote:
quoted
On 11/10/22 04:58, Greg Kroah-Hartman wrote:
quoted
On Wed, Nov 09, 2022 at 03:10:37PM -0500, Nayna wrote:
quoted
On 11/9/22 08:46, Greg Kroah-Hartman wrote:
quoted
On Sun, Nov 06, 2022 at 04:07:42PM -0500, Nayna Jain wrote:
quoted
securityfs is meant for Linux security subsystems to expose policies/logs
or any other information. However, there are various firmware security
features which expose their variables for user management via the kernel.
There is currently no single place to expose these variables. Different
platforms use sysfs/platform specific filesystem(efivarfs)/securityfs
interface as they find it appropriate. Thus, there is a gap in kernel
interfaces to expose variables for security features.
Define a firmware security filesystem (fwsecurityfs) to be used by
security features enabled by the firmware. These variables are platform
specific. This filesystem provides platforms a way to implement their
own underlying semantics by defining own inode and file operations.
Similar to securityfs, the firmware security filesystem is recommended
to be exposed on a well known mount point /sys/firmware/security.
Platforms can define their own directory or file structure under this path.
Example:
# mount -t fwsecurityfs fwsecurityfs /sys/firmware/security
Why not juset use securityfs in /sys/security/firmware/ instead? Then
you don't have to create a new filesystem and convince userspace to
mount it in a specific location?
From man 5 sysfs page:
/sys/firmware: This subdirectory contains interfaces for viewing and
manipulating firmware-specific objects and attributes.
/sys/kernel: This subdirectory contains various files and subdirectories
that provide information about the running kernel.
The security variables which are being exposed via fwsecurityfs are managed
by firmware, stored in firmware managed space and also often consumed by
firmware for enabling various security features.
Ok, then just use the normal sysfs interface for /sys/firmware, why do
you need a whole new filesystem type?
quoted
From git commit b67dbf9d4c1987c370fd18fdc4cf9d8aaea604c2, the purpose of
securityfs(/sys/kernel/security) is to provide a common place for all kernel
LSMs. The idea of
fwsecurityfs(/sys/firmware/security) is to similarly provide a common place
for all firmware security objects.
/sys/firmware already exists. The patch now defines a new /security
directory in it for firmware security features. Using /sys/kernel/security
would mean scattering firmware objects in multiple places and confusing the
purpose of /sys/kernel and /sys/firmware.
sysfs is confusing already, no problem with making it more confusing :)
Just document where you add things and all should be fine.
quoted
Even though fwsecurityfs code is based on securityfs, since the two
filesystems expose different types of objects and have different
requirements, there are distinctions:
1. fwsecurityfs lets users create files in userspace, securityfs only allows
kernel subsystems to create files.
Wait, why would a user ever create a file in this filesystem? If you
need that, why not use configfs? That's what that is for, right?
The purpose of fwsecurityfs is not to expose configuration items but rather
security objects used for firmware security features. I think these are more
comparable to EFI variables, which are exposed via an EFI-specific
filesystem, efivarfs, rather than configfs.
quoted
quoted
2. firmware and kernel objects may have different requirements. For example,
consideration of namespacing. As per my understanding, namespacing is
applied to kernel resources and not firmware resources. That's why it makes
sense to add support for namespacing in securityfs, but we concluded that
fwsecurityfs currently doesn't need it. Another but similar example of it
is: TPM space, which is exposed from hardware. For containers, the TPM would
be made as virtual/software TPM. Similarly for firmware space for
containers, it would have to be something virtualized/software version of
it.
I do not understand, sorry. What does namespaces have to do with this?
sysfs can already handle namespaces just fine, why not use that?
I do not understand, sorry. Do you want to use a namespace for these or
not? The code does not seem to be using namespaces. You can use sysfs
with, or without, a namespace so I don't understand the issue here.
With your code, there is no namespace.
You are correct. There's no namespace for these.
So again, I do not understand. Do you want to use filesystem
namespaces, or do you not?
How again can you not use sysfs or securityfs due to namespaces? What
is missing?
confused,
greg k-h
From: James Bottomley <James.Bottomley@HansenPartnership.com> Date: 2022-11-21 03:14:34
On Sun, 2022-11-20 at 17:13 +0100, Greg Kroah-Hartman wrote:
On Sat, Nov 19, 2022 at 01:20:09AM -0500, Nayna wrote:
quoted
On 11/17/22 16:27, Greg Kroah-Hartman wrote:
quoted
On Mon, Nov 14, 2022 at 06:03:43PM -0500, Nayna wrote:
quoted
On 11/10/22 04:58, Greg Kroah-Hartman wrote:
[...]
quoted
quoted
quoted
quoted
I do not understand, sorry. What does namespaces have to do
with this?
sysfs can already handle namespaces just fine, why not use
that?
Firmware objects are not namespaced. I mentioned it here as an
example of the difference between firmware and kernel objects.
It is also in response to the feedback from James Bottomley in
RFC v2 [
https://lore.kernel.org/linuxppc-dev/41ca51e8db9907d9060cc38ad
b59a66dcae4c59b.camel@HansenPartnership.com/].
I do not understand, sorry. Do you want to use a namespace for
these or not? The code does not seem to be using namespaces.
You can use sysfs with, or without, a namespace so I don't
understand the issue here.
With your code, there is no namespace.
You are correct. There's no namespace for these.
So again, I do not understand. Do you want to use filesystem
namespaces, or do you not?
Since this seems to go back to my email quoted again, let me repeat:
the question isn't if this patch is namespaced; I think you've agreed
several times it isn't. The question is if the exposed properties
would ever need to be namespaced. This is a subtle and complex
question which isn't at all explored by the above interchange.
How again can you not use sysfs or securityfs due to namespaces?
What is missing?
I already explained in the email that sysfs contains APIs like
simple_pin_... which are completely inimical to namespacing. Currently
securityfs contains them as well, so in that regard they're both no
better than each other. The point I was making is that securityfs is
getting namespaced by the IMA namespace rework (which is pretty complex
due to having to replace the simple_pin_... APIs), so when (perhaps if)
the IMA namespace is accepted, securityfs will make a good home for
quantities that need namespacing. That's not to say you can't
namespace things in sysfs, you can, in the same way that you can get a
round peg into a square hole if you bang hard enough.
So perhaps we could get back to the original question of whether these
quantities would ever be namespaced ... or, conversely, whether they
would never need namespacing.
James
On Sun, Nov 20, 2022 at 10:14:26PM -0500, James Bottomley wrote:
On Sun, 2022-11-20 at 17:13 +0100, Greg Kroah-Hartman wrote:
quoted
On Sat, Nov 19, 2022 at 01:20:09AM -0500, Nayna wrote:
quoted
On 11/17/22 16:27, Greg Kroah-Hartman wrote:
quoted
On Mon, Nov 14, 2022 at 06:03:43PM -0500, Nayna wrote:
quoted
On 11/10/22 04:58, Greg Kroah-Hartman wrote:
[...]
quoted
quoted
quoted
quoted
quoted
I do not understand, sorry. What does namespaces have to do
with this?
sysfs can already handle namespaces just fine, why not use
that?
Firmware objects are not namespaced. I mentioned it here as an
example of the difference between firmware and kernel objects.
It is also in response to the feedback from James Bottomley in
RFC v2 [
https://lore.kernel.org/linuxppc-dev/41ca51e8db9907d9060cc38ad
b59a66dcae4c59b.camel@HansenPartnership.com/].
I do not understand, sorry. Do you want to use a namespace for
these or not? The code does not seem to be using namespaces.
You can use sysfs with, or without, a namespace so I don't
understand the issue here.
With your code, there is no namespace.
You are correct. There's no namespace for these.
So again, I do not understand. Do you want to use filesystem
namespaces, or do you not?
Since this seems to go back to my email quoted again, let me repeat:
the question isn't if this patch is namespaced; I think you've agreed
several times it isn't. The question is if the exposed properties
would ever need to be namespaced. This is a subtle and complex
question which isn't at all explored by the above interchange.
quoted
How again can you not use sysfs or securityfs due to namespaces?
What is missing?
I already explained in the email that sysfs contains APIs like
simple_pin_... which are completely inimical to namespacing.
Then how does the networking code handle the namespace stuff in sysfs?
That seems to work today, or am I missing something?
If the namespace support needs to be fixed up in sysfs (or in
securityfs), then great, let's do that, and not write a whole new
filesystem just because that's not done.
Also this patch series also doesn't handle namespaces, so again, I am
totally confused as to why this is even being discussed...
thanks,
greg k-h
From: James Bottomley <James.Bottomley@HansenPartnership.com> Date: 2022-11-21 14:07:21
On Mon, 2022-11-21 at 12:05 +0100, Greg Kroah-Hartman wrote:
On Sun, Nov 20, 2022 at 10:14:26PM -0500, James Bottomley wrote:
quoted
On Sun, 2022-11-20 at 17:13 +0100, Greg Kroah-Hartman wrote:
quoted
On Sat, Nov 19, 2022 at 01:20:09AM -0500, Nayna wrote:
quoted
On 11/17/22 16:27, Greg Kroah-Hartman wrote:
quoted
On Mon, Nov 14, 2022 at 06:03:43PM -0500, Nayna wrote:
quoted
On 11/10/22 04:58, Greg Kroah-Hartman wrote:
[...]
quoted
quoted
quoted
quoted
quoted
I do not understand, sorry. What does namespaces have to
do
with this?
sysfs can already handle namespaces just fine, why not
use
that?
Firmware objects are not namespaced. I mentioned it here as
an
example of the difference between firmware and kernel
objects.
It is also in response to the feedback from James Bottomley
in
RFC v2 [
https://lore.kernel.org/linuxppc-dev/41ca51e8db9907d9060cc38ad
b59a66dcae4c59b.camel@HansenPartnership.com/].
I do not understand, sorry. Do you want to use a namespace
for
these or not? The code does not seem to be using
namespaces.
You can use sysfs with, or without, a namespace so I don't
understand the issue here.
With your code, there is no namespace.
You are correct. There's no namespace for these.
So again, I do not understand. Do you want to use filesystem
namespaces, or do you not?
Since this seems to go back to my email quoted again, let me
repeat: the question isn't if this patch is namespaced; I think
you've agreed several times it isn't. The question is if the
exposed properties would ever need to be namespaced. This is a
subtle and complex question which isn't at all explored by the
above interchange.
quoted
How again can you not use sysfs or securityfs due to namespaces?
What is missing?
I already explained in the email that sysfs contains APIs like
simple_pin_... which are completely inimical to namespacing.
Then how does the networking code handle the namespace stuff in
sysfs?
That seems to work today, or am I missing something?
have you actually tried?
jejb@lingrow:~> sudo unshare --net bash
lingrow:/home/jejb # ls /sys/class/net/
lo tun0 tun10 wlan0
lingrow:/home/jejb # ip link show
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN mode DEFAULT group
default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
So, as you see, I've entered a network namespace and ip link shows me
the only interface I can see in that namespace (a down loopback) but
sysfs shows me every interface on the system outside the namespace.
This is pretty much the story of containers and sysfs: if you mount it
inside the container, it leaks information about the host
configuration. Since I created a container with full root, I could
actually fiddle with the host network parameters on interfaces I
shouldn't be able to see within the container using sysfs ... which is
one reason we try to persuade people to use a user namespace instead of
full root.
If the namespace support needs to be fixed up in sysfs (or in
securityfs), then great, let's do that, and not write a whole new
filesystem just because that's not done.
As I said: a fix is proposed for securityfs. I think everyone in
containers concluded long ago that sysfs is too big an Augean Stable.
Also this patch series also doesn't handle namespaces, so again, I am
totally confused as to why this is even being discussed...
Well, it's not my patch. I came into this saying *if* there was ever a
reason to namespace these parameters then please don't use interfaces
inimical to namespacing. My personal view is that this should all just
go in securityfs because that defers answering the question of whether
it would eventually be namespaced.
James
On Mon, Nov 21, 2022 at 09:03:18AM -0500, James Bottomley wrote:
On Mon, 2022-11-21 at 12:05 +0100, Greg Kroah-Hartman wrote:
quoted
On Sun, Nov 20, 2022 at 10:14:26PM -0500, James Bottomley wrote:
quoted
On Sun, 2022-11-20 at 17:13 +0100, Greg Kroah-Hartman wrote:
quoted
On Sat, Nov 19, 2022 at 01:20:09AM -0500, Nayna wrote:
quoted
On 11/17/22 16:27, Greg Kroah-Hartman wrote:
quoted
On Mon, Nov 14, 2022 at 06:03:43PM -0500, Nayna wrote:
quoted
On 11/10/22 04:58, Greg Kroah-Hartman wrote:
[...]
quoted
quoted
quoted
quoted
quoted
I do not understand, sorry. What does namespaces have to
do
with this?
sysfs can already handle namespaces just fine, why not
use
that?
Firmware objects are not namespaced. I mentioned it here as
an
example of the difference between firmware and kernel
objects.
It is also in response to the feedback from James Bottomley
in
RFC v2 [
https://lore.kernel.org/linuxppc-dev/41ca51e8db9907d9060cc38ad
b59a66dcae4c59b.camel@HansenPartnership.com/].
I do not understand, sorry. Do you want to use a namespace
for
these or not? The code does not seem to be using
namespaces.
You can use sysfs with, or without, a namespace so I don't
understand the issue here.
With your code, there is no namespace.
You are correct. There's no namespace for these.
So again, I do not understand. Do you want to use filesystem
namespaces, or do you not?
Since this seems to go back to my email quoted again, let me
repeat: the question isn't if this patch is namespaced; I think
you've agreed several times it isn't. The question is if the
exposed properties would ever need to be namespaced. This is a
subtle and complex question which isn't at all explored by the
above interchange.
quoted
How again can you not use sysfs or securityfs due to namespaces?
What is missing?
I already explained in the email that sysfs contains APIs like
simple_pin_... which are completely inimical to namespacing.
Then how does the networking code handle the namespace stuff in
sysfs?
That seems to work today, or am I missing something?
have you actually tried?
jejb@lingrow:~> sudo unshare --net bash
lingrow:/home/jejb # ls /sys/class/net/
lo tun0 tun10 wlan0
lingrow:/home/jejb # ip link show
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN mode DEFAULT group
default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
So, as you see, I've entered a network namespace and ip link shows me
the only interface I can see in that namespace (a down loopback) but
sysfs shows me every interface on the system outside the namespace.
Then all of the code in include/kobject_ns.h is not being used? We have
a whole kobject namespace set up for networking, I just assumed they
were using it. If not, I'm all for ripping it out.
thanks,
greg k-h
From: David Laight <hidden> Date: 2022-11-21 16:13:06
From: James Bottomley
Sent: 21 November 2022 14:03
...
quoted
Then how does the networking code handle the namespace stuff in
sysfs?
That seems to work today, or am I missing something?
have you actually tried?
jejb@lingrow:~> sudo unshare --net bash
lingrow:/home/jejb # ls /sys/class/net/
lo tun0 tun10 wlan0
lingrow:/home/jejb # ip link show
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN mode DEFAULT group
default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
So, as you see, I've entered a network namespace and ip link shows me
the only interface I can see in that namespace (a down loopback) but
sysfs shows me every interface on the system outside the namespace.
You have to remount /sys to get the restricted copy.
eg by running 'ip netns exec namespace command'.
David
-
Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK
Registration No: 1397386 (Wales)
From: James Bottomley <James.Bottomley@HansenPartnership.com> Date: 2022-11-21 17:34:06
On Mon, 2022-11-21 at 16:05 +0100, Greg Kroah-Hartman wrote:
On Mon, Nov 21, 2022 at 09:03:18AM -0500, James Bottomley wrote:
quoted
On Mon, 2022-11-21 at 12:05 +0100, Greg Kroah-Hartman wrote:
quoted
On Sun, Nov 20, 2022 at 10:14:26PM -0500, James Bottomley wrote:
[...]
quoted
quoted
quoted
I already explained in the email that sysfs contains APIs like
simple_pin_... which are completely inimical to namespacing.
Then how does the networking code handle the namespace stuff in
sysfs? That seems to work today, or am I missing something?
have you actually tried?
jejb@lingrow:~> sudo unshare --net bash
lingrow:/home/jejb # ls /sys/class/net/
lo tun0 tun10 wlan0
lingrow:/home/jejb # ip link show
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN mode DEFAULT
group
default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
So, as you see, I've entered a network namespace and ip link shows
me the only interface I can see in that namespace (a down loopback)
but sysfs shows me every interface on the system outside the
namespace.
Then all of the code in include/kobject_ns.h is not being used? We
have a whole kobject namespace set up for networking, I just assumed
they were using it. If not, I'm all for ripping it out.
Hm, looking at the implementation, it seems to trigger off the
superblock (meaning you have to remount inside a mount namespace) and
it only works to control visibility in label based namespaces, so this
does actually work
jejb@lingrow:~/git/linux> sudo unshare --net --mount bash
lingrow:/home/jejb # mount -t sysfs none /sys
lingrow:/home/jejb # ls /sys/class/net/
lo
The label based approach means that any given file can be shown in one
and only one namespace, which works for net, but not much else
(although it probably could be adapted).
James
On Mon, Nov 21, 2022 at 12:33:55PM -0500, James Bottomley wrote:
On Mon, 2022-11-21 at 16:05 +0100, Greg Kroah-Hartman wrote:
quoted
On Mon, Nov 21, 2022 at 09:03:18AM -0500, James Bottomley wrote:
quoted
On Mon, 2022-11-21 at 12:05 +0100, Greg Kroah-Hartman wrote:
quoted
On Sun, Nov 20, 2022 at 10:14:26PM -0500, James Bottomley wrote:
[...]
quoted
quoted
quoted
quoted
I already explained in the email that sysfs contains APIs like
simple_pin_... which are completely inimical to namespacing.
Then how does the networking code handle the namespace stuff in
sysfs? That seems to work today, or am I missing something?
have you actually tried?
jejb@lingrow:~> sudo unshare --net bash
lingrow:/home/jejb # ls /sys/class/net/
lo tun0 tun10 wlan0
lingrow:/home/jejb # ip link show
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN mode DEFAULT
group
default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
So, as you see, I've entered a network namespace and ip link shows
me the only interface I can see in that namespace (a down loopback)
but sysfs shows me every interface on the system outside the
namespace.
Then all of the code in include/kobject_ns.h is not being used? We
have a whole kobject namespace set up for networking, I just assumed
they were using it. If not, I'm all for ripping it out.
Hm, looking at the implementation, it seems to trigger off the
superblock (meaning you have to remount inside a mount namespace) and
it only works to control visibility in label based namespaces, so this
does actually work
jejb@lingrow:~/git/linux> sudo unshare --net --mount bash
lingrow:/home/jejb # mount -t sysfs none /sys
lingrow:/home/jejb # ls /sys/class/net/
lo
The label based approach means that any given file can be shown in one
and only one namespace, which works for net, but not much else
(although it probably could be adapted).
Great, thanks for verifying it works properly.
No other subsystem other than networking has cared about adding support
for namespaces to their sysfs representations. But the base logic is
all there if they want to do so.
thanks,
greg k-h
On Sun, 2022-11-20 at 17:13 +0100, Greg Kroah-Hartman wrote:
quoted
On Sat, Nov 19, 2022 at 01:20:09AM -0500, Nayna wrote:
quoted
On 11/17/22 16:27, Greg Kroah-Hartman wrote:
quoted
On Mon, Nov 14, 2022 at 06:03:43PM -0500, Nayna wrote:
quoted
On 11/10/22 04:58, Greg Kroah-Hartman wrote:
[...]
quoted
quoted
[...]
quoted
quoted
You are correct. There's no namespace for these.
So again, I do not understand. Do you want to use filesystem
namespaces, or do you not?
Since this seems to go back to my email quoted again, let me repeat:
the question isn't if this patch is namespaced; I think you've agreed
several times it isn't. The question is if the exposed properties
would ever need to be namespaced. This is a subtle and complex
question which isn't at all explored by the above interchange.
quoted
How again can you not use sysfs or securityfs due to namespaces?
What is missing?
I already explained in the email that sysfs contains APIs like
simple_pin_... which are completely inimical to namespacing. Currently
securityfs contains them as well, so in that regard they're both no
better than each other. The point I was making is that securityfs is
getting namespaced by the IMA namespace rework (which is pretty complex
due to having to replace the simple_pin_... APIs), so when (perhaps if)
the IMA namespace is accepted, securityfs will make a good home for
quantities that need namespacing. That's not to say you can't
namespace things in sysfs, you can, in the same way that you can get a
round peg into a square hole if you bang hard enough.
So perhaps we could get back to the original question of whether these
quantities would ever be namespaced ... or, conversely, whether they
would never need namespacing.
To clarify, I brought up in the discussion about namespacing
considerations because I was asked about them. However, I determined
there were none because firmware object interactions are invariant
across namespaces. I don't see this changing in the future given that
the firmware objects have no notion of namespacing.
Thanks & Regards,
- Nayna
On Sun, Nov 06, 2022 at 04:07:42PM -0500, Nayna Jain wrote:
quoted
securityfs is meant for Linux security subsystems to expose policies/logs
or any other information. However, there are various firmware security
features which expose their variables for user management via the kernel.
There is currently no single place to expose these variables. Different
platforms use sysfs/platform specific filesystem(efivarfs)/securityfs
interface as they find it appropriate. Thus, there is a gap in kernel
interfaces to expose variables for security features.
Define a firmware security filesystem (fwsecurityfs) to be used by
security features enabled by the firmware. These variables are platform
specific. This filesystem provides platforms a way to implement their
own underlying semantics by defining own inode and file operations.
Similar to securityfs, the firmware security filesystem is recommended
to be exposed on a well known mount point /sys/firmware/security.
Platforms can define their own directory or file structure under this path.
Example:
# mount -t fwsecurityfs fwsecurityfs /sys/firmware/security
Why not juset use securityfs in /sys/security/firmware/ instead? Then
you don't have to create a new filesystem and convince userspace to
mount it in a specific location?
I am also curious to know on why not use securityfs, given the similarity
between the two. :)
More specifics on that below...
quoted
From man 5 sysfs page:
/sys/firmware: This subdirectory contains interfaces for viewing and
manipulating firmware-specific objects and attributes.
/sys/kernel: This subdirectory contains various files and subdirectories
that provide information about the running kernel.
The security variables which are being exposed via fwsecurityfs are managed
by firmware, stored in firmware managed space and also often consumed by
firmware for enabling various security features.
That's ok. As I see it users of securityfs can define their own fileops
(like how you are doing in fwsecurityfs).
See securityfs_create_file() & securityfs_create_symlink(), can accept the fops
& iops. Except maybe securityfs_create_dir(), that could be since there might
not be a usecase for it. But do you also need it in your case is the question to
ask.
Please refer to the function plpks_secvars_init() in Patch 4/4.
quoted
From git commit b67dbf9d4c1987c370fd18fdc4cf9d8aaea604c2, the purpose of
securityfs(/sys/kernel/security) is to provide a common place for all kernel
LSMs. The idea of
Which was then seperated out by commit,
da31894ed7b654e2 ("securityfs: do not depend on CONFIG_SECURITY").
securityfs now has a seperate CONFIG_SECURITYFS config option. In fact I was even
thinking of why shouldn't we move security/inode.c into fs/securityfs/inode.c .
fs/* is a common place for all filesystems. Users of securityfs can call it's
exported kernel APIs to create files/dirs/symlinks.
If we move security/inode.c to fs/security/inode.c, then...
...below call within securityfs_init() should be moved into some lsm sepecific
file.
#ifdef CONFIG_SECURITY
static struct dentry *lsm_dentry;
static ssize_t lsm_read(struct file *filp, char __user *buf, size_t count,
loff_t *ppos)
{
return simple_read_from_buffer(buf, count, ppos, lsm_names,
strlen(lsm_names));
}
static const struct file_operations lsm_ops = {
.read = lsm_read,
.llseek = generic_file_llseek,
};
#endif
securityfs_init()
#ifdef CONFIG_SECURITY
lsm_dentry = securityfs_create_file("lsm", 0444, NULL, NULL,
&lsm_ops);
#endif
So why not move it? Maybe others, can comment more on whether it's a good idea
to move security/inode.c into fs/security/inode.c?
This should then help others identify securityfs filesystem in fs/security/
for everyone to notice and utilize for their use?
quoted
fwsecurityfs(/sys/firmware/security) is to similarly provide a common place
for all firmware security objects.
/sys/firmware already exists. The patch now defines a new /security
directory in it for firmware security features. Using /sys/kernel/security
would mean scattering firmware objects in multiple places and confusing the
purpose of /sys/kernel and /sys/firmware.
We can also think of it this way that, all security related exports should
happen via /sys/kernel/security/. Then /sys/kernel/security/firmware/ becomes
the security related firmware exports.
If you see find /sys -iname firmware, I am sure you will find other firmware
specifics directories related to other specific subsystems
(e.g.
root@qemu:/home/qemu# find /sys -iname firmware
/sys/devices/ndbus0/nmem0/firmware
/sys/devices/ndbus0/firmware
/sys/firmware
)
But it could be, I am not an expert here, although I was thinking a good
Documentation might solve this problem.
Documentation on
sysfs(https://man7.org/linux/man-pages/man5/sysfs.5.html) already
differentiates /sys/firmware and /sys/kernel as I responded earlier.
The objects we are exposing are firmware objects and not kernel objects.
quoted
Even though fwsecurityfs code is based on securityfs, since the two
filesystems expose different types of objects and have different
requirements, there are distinctions:
1. fwsecurityfs lets users create files in userspace, securityfs only allows
kernel subsystems to create files.
Sorry could you please elaborate how? both securityfs & fwsecurityfs
calls simple_fill_super() which uses the same inode (i_op) and inode file
operations (i_fop) from fs/libfs.c for their root inode. So how it is enabling
user (as in userspace) to create a file in this filesystem?
So am I missing anything?
The ability to let user(as in userspace) to create a file in a
filesystem comes by allowing to define inode operations.
Please look at the implementation differences for functions
xxx_create_dir() and xxx_create_dentry() of securityfs vs fwsecurityfs.
Also refer to Patch 4/4 for use of fwsecurityfs_create_dir() where inode
operations are defined.
quoted
2. firmware and kernel objects may have different requirements. For example,
consideration of namespacing. As per my understanding, namespacing is
applied to kernel resources and not firmware resources. That's why it makes
sense to add support for namespacing in securityfs, but we concluded that
fwsecurityfs currently doesn't need it. Another but similar example of it
It "currently" doesn't need it. But can it in future? Then why not go with
securityfs which has an additional namespacing feature available?
That's actually also the point of utilizing an existing FS which can get
features like this in future. As long as it doesn't affect the functionality
of your use case, we simply need not reject securityfs, no?
Thanks for your review and feedback. To summarize:
From the perspective of our use case, we need to expose firmware
security objects to userspace for management. Not all of the objects
pre-exist and we would like to allow root to create them from userspace.
From a unification perspective, I have considered a common location at
/sys/firmware/security for managing any platform's security objects. And
I've proposed a generic filesystem, which could be used by any platform
to represent firmware security objects via /sys/firmware/security.
Here are some alternatives to generic filesystem in discussion:
1. Start with a platform-specific filesystem. If more platforms would
like to use the approach, it can be made generic. We would still have a
common location of /sys/firmware/security and new code would live in
arch. This is my preference and would be the best fit for our use case.
2. Use securityfs. This would mean modifying it to satisfy other use
cases, including supporting userspace file creation. I don't know if the
securityfs maintainer would find that acceptable. I would also still
want some way to expose variables at /sys/firmware/security.
3. Use a sysfs-based approach. This would be a platform-specific
implementation. However, sysfs has a similar issue to securityfs for
file creation. When I tried it in RFC v1[1], I had to implement a
workaround to achieve that.
[1]
https://lore.kernel.org/linuxppc-dev/20220122005637.28199-3-nayna@linux.ibm.com/
Thanks & Regards,
- Nayna
From the perspective of our use case, we need to expose firmware
security objects to userspace for management. Not all of the objects
pre-exist and we would like to allow root to create them from userspace.
From a unification perspective, I have considered a common location at
/sys/firmware/security for managing any platform's security objects.
And I've proposed a generic filesystem, which could be used by any
platform to represent firmware security objects via
/sys/firmware/security.
Here are some alternatives to generic filesystem in discussion:
1. Start with a platform-specific filesystem. If more platforms would
like to use the approach, it can be made generic. We would still have
a common location of /sys/firmware/security and new code would live in
arch. This is my preference and would be the best fit for our use case.
2. Use securityfs. This would mean modifying it to satisfy other use
cases, including supporting userspace file creation. I don't know if
the securityfs maintainer would find that acceptable. I would also
still want some way to expose variables at /sys/firmware/security.
3. Use a sysfs-based approach. This would be a platform-specific
implementation. However, sysfs has a similar issue to securityfs for
file creation. When I tried it in RFC v1[1], I had to implement a
workaround to achieve that.
[1]
https://lore.kernel.org/linuxppc-dev/20220122005637.28199-3-nayna@linux.ibm.com/
Hi Greg,
Based on the discussions so far, is Option 1, described above, an
acceptable next step?
Thanks & Regards,
- Nayna
On Wed, Nov 23, 2022 at 10:05:49AM -0500, Nayna wrote:
On 11/22/22 18:21, Nayna wrote:
quoted
From the perspective of our use case, we need to expose firmware
security objects to userspace for management. Not all of the objects
pre-exist and we would like to allow root to create them from userspace.
From a unification perspective, I have considered a common location at
/sys/firmware/security for managing any platform's security objects. And
I've proposed a generic filesystem, which could be used by any platform
to represent firmware security objects via /sys/firmware/security.
Here are some alternatives to generic filesystem in discussion:
1. Start with a platform-specific filesystem. If more platforms would
like to use the approach, it can be made generic. We would still have a
common location of /sys/firmware/security and new code would live in
arch. This is my preference and would be the best fit for our use case.
2. Use securityfs. This would mean modifying it to satisfy other use
cases, including supporting userspace file creation. I don't know if the
securityfs maintainer would find that acceptable. I would also still
want some way to expose variables at /sys/firmware/security.
3. Use a sysfs-based approach. This would be a platform-specific
implementation. However, sysfs has a similar issue to securityfs for
file creation. When I tried it in RFC v1[1], I had to implement a
workaround to achieve that.
[1] https://lore.kernel.org/linuxppc-dev/20220122005637.28199-3-nayna@linux.ibm.com/
Hi Greg,
Based on the discussions so far, is Option 1, described above, an acceptable
next step?
No, as I said almost a year ago, I do not want to see platform-only
filesystems going and implementing stuff that should be shared by all
platforms.
thanks,
greg k-h
On Wed, Nov 23, 2022 at 10:05:49AM -0500, Nayna wrote:
quoted
On 11/22/22 18:21, Nayna wrote:
quoted
From the perspective of our use case, we need to expose firmware
security objects to userspace for management. Not all of the objects
pre-exist and we would like to allow root to create them from userspace.
From a unification perspective, I have considered a common location at
/sys/firmware/security for managing any platform's security objects. And
I've proposed a generic filesystem, which could be used by any platform
to represent firmware security objects via /sys/firmware/security.
Here are some alternatives to generic filesystem in discussion:
1. Start with a platform-specific filesystem. If more platforms would
like to use the approach, it can be made generic. We would still have a
common location of /sys/firmware/security and new code would live in
arch. This is my preference and would be the best fit for our use case.
2. Use securityfs. This would mean modifying it to satisfy other use
cases, including supporting userspace file creation. I don't know if the
securityfs maintainer would find that acceptable. I would also still
want some way to expose variables at /sys/firmware/security.
3. Use a sysfs-based approach. This would be a platform-specific
implementation. However, sysfs has a similar issue to securityfs for
file creation. When I tried it in RFC v1[1], I had to implement a
workaround to achieve that.
[1] https://lore.kernel.org/linuxppc-dev/20220122005637.28199-3-nayna@linux.ibm.com/
Hi Greg,
Based on the discussions so far, is Option 1, described above, an acceptable
next step?
No, as I said almost a year ago, I do not want to see platform-only
filesystems going and implementing stuff that should be shared by all
platforms.
Given there are no other exploiters for fwsecurityfs and there should be
no platform-specific fs, would modifying sysfs now to let userspace
create files cleanly be the way forward? Or, if we should strongly
consider securityfs, which would result in updating securityfs to allow
userspace creation of files and then expose variables via a more
platform-specific directory /sys/kernel/security/pks? We want to pick
the best available option and would find some hints on direction helpful
before we develop the next patch.
Thanks & Regards,
- Nayna
From: Andrew Donnellan <hidden> Date: 2022-12-12 01:00:26
On Wed, 2022-11-23 at 13:57 -0500, Nayna wrote:
Given there are no other exploiters for fwsecurityfs and there should
be
no platform-specific fs, would modifying sysfs now to let userspace
create files cleanly be the way forward? Or, if we should strongly
consider securityfs, which would result in updating securityfs to
allow
userspace creation of files and then expose variables via a more
platform-specific directory /sys/kernel/security/pks? We want to pick
the best available option and would find some hints on direction
helpful
before we develop the next patch.
Ping - it would be helpful for us to know your thoughts on this.
Andrew
--
Andrew Donnellan OzLabs, ADL Canberra
ajd@linux.ibm.com IBM Australia Limited
On Mon, Dec 12, 2022 at 11:58:56AM +1100, Andrew Donnellan wrote:
On Wed, 2022-11-23 at 13:57 -0500, Nayna wrote:
quoted
Given there are no other exploiters for fwsecurityfs and there should
be
no platform-specific fs, would modifying sysfs now to let userspace
create files cleanly be the way forward? Or, if we should strongly
consider securityfs, which would result in updating securityfs to
allow
userspace creation of files and then expose variables via a more
platform-specific directory /sys/kernel/security/pks? We want to pick
the best available option and would find some hints on direction
helpful
before we develop the next patch.
Ping - it would be helpful for us to know your thoughts on this.
sysfs is not for userspace creation of files, you all know this :)
greg k-h