@@ -37,6 +37,8 @@ static void report_load(const char *origin, struct file *file, char *operation)
3737}
3838
3939static int enforce = IS_ENABLED (CONFIG_SECURITY_LOADPIN_ENFORCE );
40+ static char * exclude_read_files [READING_MAX_ID ];
41+ static int ignore_read_file_id [READING_MAX_ID ] __ro_after_init ;
4042static struct super_block * pinned_root ;
4143static DEFINE_SPINLOCK (pinned_root_spinlock );
4244
@@ -121,6 +123,13 @@ static int loadpin_read_file(struct file *file, enum kernel_read_file_id id)
121123 struct super_block * load_root ;
122124 const char * origin = kernel_read_file_id_str (id );
123125
126+ /* If the file id is excluded, ignore the pinning. */
127+ if ((unsigned int )id < ARRAY_SIZE (ignore_read_file_id ) &&
128+ ignore_read_file_id [id ]) {
129+ report_load (origin , file , "pinning-excluded" );
130+ return 0 ;
131+ }
132+
124133 /* This handles the older init_module API that has a NULL file. */
125134 if (!file ) {
126135 if (!enforce ) {
@@ -179,10 +188,47 @@ static struct security_hook_list loadpin_hooks[] __lsm_ro_after_init = {
179188 LSM_HOOK_INIT (kernel_load_data , loadpin_load_data ),
180189};
181190
191+ static void __init parse_exclude (void )
192+ {
193+ int i , j ;
194+ char * cur ;
195+
196+ /*
197+ * Make sure all the arrays stay within expected sizes. This
198+ * is slightly weird because kernel_read_file_str[] includes
199+ * READING_MAX_ID, which isn't actually meaningful here.
200+ */
201+ BUILD_BUG_ON (ARRAY_SIZE (exclude_read_files ) !=
202+ ARRAY_SIZE (ignore_read_file_id ));
203+ BUILD_BUG_ON (ARRAY_SIZE (kernel_read_file_str ) <
204+ ARRAY_SIZE (ignore_read_file_id ));
205+
206+ for (i = 0 ; i < ARRAY_SIZE (exclude_read_files ); i ++ ) {
207+ cur = exclude_read_files [i ];
208+ if (!cur )
209+ break ;
210+ if (* cur == '\0' )
211+ continue ;
212+
213+ for (j = 0 ; j < ARRAY_SIZE (ignore_read_file_id ); j ++ ) {
214+ if (strcmp (cur , kernel_read_file_str [j ]) == 0 ) {
215+ pr_info ("excluding: %s\n" ,
216+ kernel_read_file_str [j ]);
217+ ignore_read_file_id [j ] = 1 ;
218+ /*
219+ * Can not break, because one read_file_str
220+ * may map to more than on read_file_id.
221+ */
222+ }
223+ }
224+ }
225+ }
226+
182227static int __init loadpin_init (void )
183228{
184229 pr_info ("ready to pin (currently %senforcing)\n" ,
185230 enforce ? "" : "not " );
231+ parse_exclude ();
186232 security_add_hooks (loadpin_hooks , ARRAY_SIZE (loadpin_hooks ), "loadpin" );
187233 return 0 ;
188234}
@@ -195,3 +241,5 @@ DEFINE_LSM(loadpin) = {
195241/* Should not be mutable after boot, so not listed in sysfs (perm == 0). */
196242module_param (enforce , int , 0 );
197243MODULE_PARM_DESC (enforce , "Enforce module/firmware pinning" );
244+ module_param_array_named (exclude , exclude_read_files , charp , NULL , 0 );
245+ MODULE_PARM_DESC (exclude , "Exclude pinning specific read file types" );
0 commit comments