@@ -221,6 +221,7 @@ pub enum PEType {
221
221
222
222
#[ derive( Debug ) ]
223
223
pub struct Type2Entry < ObjectID : FsVerityHashValue > {
224
+ pub kver : Option < Box < OsStr > > ,
224
225
// This is the path (relative to /boot/EFI/Linux) of the file
225
226
pub file_path : PathBuf ,
226
227
// The Portable Executable binary
@@ -239,40 +240,44 @@ impl<ObjectID: FsVerityHashValue> Type2Entry<ObjectID> {
239
240
}
240
241
}
241
242
242
- fn recurse_dir (
243
+ // Find UKI components, the UKI PE binary and other UKI addons,
244
+ // if any, in the provided directory
245
+ fn find_uki_components (
243
246
dir : & Directory < ObjectID > ,
244
247
entries : & mut Vec < Self > ,
245
248
path : & mut PathBuf ,
249
+ kver : & Option < Box < OsStr > > ,
246
250
) -> Result < ( ) > {
247
251
for ( filename, inode) in dir. entries ( ) {
248
252
path. push ( filename) ;
249
253
250
- // We also want to collect all UKI extensions
254
+ // Collect all UKI extensions
255
+ // Usually we'll find them in the root with directories ending in `.efi.extra.d` for kernel
256
+ // specific addons. Global addons are found in `loader/addons`
251
257
if let Inode :: Directory ( dir) = inode {
252
- if !filename. as_bytes ( ) . ends_with ( EFI_ADDON_DIR_EXT . as_bytes ( ) ) {
253
- continue ;
254
- }
255
-
256
- Type2Entry :: recurse_dir ( dir, entries, path) ?;
257
- return Ok ( ( ) ) ;
258
+ Self :: find_uki_components ( dir, entries, path, kver) ?;
259
+ path. pop ( ) ;
260
+ continue ;
258
261
}
259
262
260
263
if !filename. as_bytes ( ) . ends_with ( EFI_EXT . as_bytes ( ) ) {
264
+ path. pop ( ) ;
261
265
continue ;
262
266
}
263
267
264
268
let Inode :: Leaf ( leaf) = inode else {
265
- bail ! ( "/boot/EFI/Linux/ {filename:?} is a directory" ) ;
269
+ bail ! ( "{filename:?} is a directory" ) ;
266
270
} ;
267
271
268
272
let LeafContent :: Regular ( file) = & leaf. content else {
269
- bail ! ( "/boot/EFI/Linux/ {filename:?} is not a regular file" ) ;
273
+ bail ! ( "{filename:?} is not a regular file" ) ;
270
274
} ;
271
275
272
276
entries. push ( Self {
277
+ kver : kver. clone ( ) ,
273
278
file_path : path. clone ( ) ,
274
279
file : file. clone ( ) ,
275
- pe_type : if path. components ( ) . count ( ) == 1 {
280
+ pe_type : if path. components ( ) . count ( ) == 0 {
276
281
PEType :: Uki
277
282
} else {
278
283
PEType :: UkiAddon
@@ -290,84 +295,25 @@ impl<ObjectID: FsVerityHashValue> Type2Entry<ObjectID> {
290
295
291
296
match root. get_directory ( "/boot/EFI/Linux" . as_ref ( ) ) {
292
297
Ok ( entries_dir) => {
293
- Type2Entry :: recurse_dir ( entries_dir, & mut entries, & mut PathBuf :: new ( ) ) ?
298
+ Self :: find_uki_components ( entries_dir, & mut entries, & mut PathBuf :: new ( ) , & None ) ?
294
299
}
295
300
Err ( ImageError :: NotFound ( ..) ) => { }
296
301
Err ( other) => Err ( other) ?,
297
302
} ;
298
303
299
- Ok ( entries)
300
- }
301
- }
302
-
303
- #[ derive( Debug ) ]
304
- pub struct UsrLibModulesUki < ObjectID : FsVerityHashValue > {
305
- pub kver : Box < OsStr > ,
306
- pub file_path : PathBuf ,
307
- pub file : RegularFile < ObjectID > ,
308
- pub pe_type : PEType ,
309
- }
310
-
311
- impl < ObjectID : FsVerityHashValue > UsrLibModulesUki < ObjectID > {
312
- fn recurse_dir (
313
- dir : & Directory < ObjectID > ,
314
- entries : & mut Vec < Self > ,
315
- path : & mut PathBuf ,
316
- kver : & OsStr ,
317
- ) -> Result < ( ) > {
318
- for ( filename, inode) in dir. entries ( ) {
319
- path. push ( filename) ;
320
-
321
- // Collect all UKI extensions
322
- if let Inode :: Directory ( dir) = inode {
323
- if !filename. as_bytes ( ) . ends_with ( EFI_ADDON_DIR_EXT . as_bytes ( ) ) {
324
- continue ;
325
- }
326
-
327
- UsrLibModulesUki :: recurse_dir ( dir, entries, path, kver) ?;
328
- return Ok ( ( ) ) ;
329
- }
330
-
331
- if !filename. as_bytes ( ) . ends_with ( EFI_EXT . as_bytes ( ) ) {
332
- continue ;
333
- }
334
-
335
- let Inode :: Leaf ( leaf) = inode else {
336
- bail ! ( "/usr/lib/modules/{filename:?} is a directory" ) ;
337
- } ;
338
-
339
- let LeafContent :: Regular ( file) = & leaf. content else {
340
- bail ! ( "/usr/lib/modules/{filename:?} is not a regular file" ) ;
341
- } ;
342
-
343
- entries. push ( Self {
344
- kver : Box :: from ( kver) ,
345
- file_path : path. clone ( ) ,
346
- file : file. clone ( ) ,
347
- pe_type : if path. components ( ) . count ( ) == 0 {
348
- PEType :: Uki
349
- } else {
350
- PEType :: UkiAddon
351
- } ,
352
- } ) ;
353
-
354
- path. pop ( ) ;
355
- }
356
-
357
- Ok ( ( ) )
358
- }
359
-
360
- pub fn load_all ( root : & Directory < ObjectID > ) -> Result < Vec < Self > > {
361
- let mut entries = vec ! [ ] ;
362
-
363
304
match root. get_directory ( "/usr/lib/modules" . as_ref ( ) ) {
364
305
Ok ( modules_dir) => {
365
306
for ( kver, inode) in modules_dir. entries ( ) {
366
307
let Inode :: Directory ( dir) = inode else {
367
308
continue ;
368
309
} ;
369
310
370
- UsrLibModulesUki :: recurse_dir ( dir, & mut entries, & mut PathBuf :: new ( ) , kver) ?;
311
+ Self :: find_uki_components (
312
+ dir,
313
+ & mut entries,
314
+ & mut PathBuf :: new ( ) ,
315
+ & Some ( Box :: from ( kver) ) ,
316
+ ) ?;
371
317
}
372
318
}
373
319
Err ( ImageError :: NotFound ( ..) ) => { }
@@ -452,7 +398,7 @@ initrd /{id}/initramfs.img
452
398
pub enum BootEntry < ObjectID : FsVerityHashValue > {
453
399
Type1 ( Type1Entry < ObjectID > ) ,
454
400
Type2 ( Type2Entry < ObjectID > ) ,
455
- UsrLibModulesUki ( UsrLibModulesUki < ObjectID > ) ,
401
+ UsrLibModulesUki ( Type2Entry < ObjectID > ) ,
456
402
UsrLibModulesVmLinuz ( UsrLibModulesVmlinuz < ObjectID > ) ,
457
403
}
458
404
@@ -468,9 +414,6 @@ pub fn get_boot_resources<ObjectID: FsVerityHashValue>(
468
414
for e in Type2Entry :: load_all ( & image. root ) ? {
469
415
entries. push ( BootEntry :: Type2 ( e) ) ;
470
416
}
471
- for e in UsrLibModulesUki :: load_all ( & image. root ) ? {
472
- entries. push ( BootEntry :: UsrLibModulesUki ( e) ) ;
473
- }
474
417
for e in UsrLibModulesVmlinuz :: load_all ( & image. root ) ? {
475
418
entries. push ( BootEntry :: UsrLibModulesVmLinuz ( e) ) ;
476
419
}
0 commit comments