@@ -9,7 +9,7 @@ use composefs::{
9
9
tree:: { Directory , FileSystem , ImageError , Inode , LeafContent , RegularFile } ,
10
10
} ;
11
11
12
- use crate :: cmdline:: { make_cmdline_composefs , split_cmdline } ;
12
+ use crate :: cmdline:: { Cmdline , Parameter } ;
13
13
14
14
/// Strips the key (if it matches) plus the following whitespace from a single line in a "Type #1
15
15
/// Boot Loader Specification Entry" file.
@@ -65,30 +65,17 @@ impl BootLoaderEntryFile {
65
65
///
66
66
/// arg can be something like "composefs=xyz" but it can also be something like "rw". In
67
67
/// either case, if the argument already existed, it will be replaced.
68
- pub fn add_cmdline ( & mut self , arg : & str ) {
69
- let key = match arg. find ( '=' ) {
70
- Some ( pos) => & arg[ ..=pos] , // include the '='
71
- None => arg,
72
- } ;
73
-
68
+ pub fn add_cmdline ( & mut self , arg : & Parameter ) {
74
69
// There are three possible paths in this function:
75
70
// 1. options line with key= already in it (replace it)
76
71
// 2. options line with no key= in it (append key=value)
77
72
// 3. no options line (append the entire thing)
78
73
for line in & mut self . lines {
79
74
if let Some ( cmdline) = strip_ble_key ( line, "options" ) {
80
- let segment = split_cmdline ( cmdline) . find ( |s| s. starts_with ( key) ) ;
81
-
82
- if let Some ( old) = segment {
83
- // 1. Replace existing key
84
- let range = substr_range ( line, old) . unwrap ( ) ;
85
- line. replace_range ( range, arg) ;
86
- } else {
87
- // 2. Append new argument
88
- line. push ( ' ' ) ;
89
- line. push_str ( arg) ;
90
- }
75
+ let mut cmdline = Cmdline :: from ( cmdline) ;
76
+ cmdline. add_or_modify ( arg) ;
91
77
78
+ * line = format ! ( "options {cmdline}" ) ;
92
79
return ;
93
80
}
94
81
}
@@ -99,9 +86,21 @@ impl BootLoaderEntryFile {
99
86
100
87
/// Adjusts the kernel command-line arguments by adding a composefs= parameter (if appropriate)
101
88
/// and adding additional arguments, as requested.
102
- pub fn adjust_cmdline ( & mut self , composefs : Option < & str > , insecure : bool , extra : & [ & str ] ) {
89
+ pub fn adjust_cmdline < T : FsVerityHashValue > (
90
+ & mut self ,
91
+ composefs : Option < & T > ,
92
+ insecure : bool ,
93
+ extra : & [ Parameter ] ,
94
+ ) {
103
95
if let Some ( id) = composefs {
104
- self . add_cmdline ( & make_cmdline_composefs ( id, insecure) ) ;
96
+ let id = id. to_hex ( ) ;
97
+ let cfs_str = match insecure {
98
+ true => format ! ( "composefs=?{id}" ) ,
99
+ false => format ! ( "composefs={id}" ) ,
100
+ } ;
101
+
102
+ let param = Parameter :: parse ( & cfs_str) . unwrap ( ) ;
103
+ self . add_cmdline ( & param) ;
105
104
}
106
105
107
106
for item in extra {
@@ -400,8 +399,27 @@ pub fn get_boot_resources<ObjectID: FsVerityHashValue>(
400
399
401
400
#[ cfg( test) ]
402
401
mod tests {
402
+ use composefs:: fsverity:: Sha256HashValue ;
403
+ use zerocopy:: FromZeros ;
404
+
403
405
use super :: * ;
404
406
407
+ fn sha256 ( ) -> Sha256HashValue {
408
+ Sha256HashValue :: new_zeroed ( )
409
+ }
410
+
411
+ fn sha256str ( ) -> String {
412
+ sha256 ( ) . to_hex ( )
413
+ }
414
+
415
+ fn param ( input : & str ) -> Parameter < ' _ > {
416
+ Parameter :: parse ( input) . unwrap ( )
417
+ }
418
+
419
+ fn params < ' a > ( input : & ' a [ & ' a str ] ) -> Vec < Parameter < ' a > > {
420
+ input. iter ( ) . map ( |p| param ( * p) ) . collect ( )
421
+ }
422
+
405
423
#[ test]
406
424
fn test_bootloader_entry_file_new ( ) {
407
425
let content = "title Test Entry\n version 1.0\n linux /vmlinuz\n initrd /initramfs.img\n options quiet splash\n " ;
@@ -490,7 +508,7 @@ mod tests {
490
508
#[ test]
491
509
fn test_add_cmdline_new_options_line ( ) {
492
510
let mut entry = BootLoaderEntryFile :: new ( "title Test Entry\n linux /vmlinuz\n " ) ;
493
- entry. add_cmdline ( "quiet" ) ;
511
+ entry. add_cmdline ( & param ( "quiet" ) ) ;
494
512
495
513
assert_eq ! ( entry. lines. len( ) , 3 ) ;
496
514
assert_eq ! ( entry. lines[ 2 ] , "options quiet" ) ;
@@ -499,7 +517,7 @@ mod tests {
499
517
#[ test]
500
518
fn test_add_cmdline_append_to_existing_options ( ) {
501
519
let mut entry = BootLoaderEntryFile :: new ( "title Test Entry\n options splash\n " ) ;
502
- entry. add_cmdline ( "quiet" ) ;
520
+ entry. add_cmdline ( & param ( "quiet" ) ) ;
503
521
504
522
assert_eq ! ( entry. lines. len( ) , 2 ) ;
505
523
assert_eq ! ( entry. lines[ 1 ] , "options splash quiet" ) ;
@@ -509,7 +527,7 @@ mod tests {
509
527
fn test_add_cmdline_replace_existing_key_value ( ) {
510
528
let mut entry =
511
529
BootLoaderEntryFile :: new ( "title Test Entry\n options quiet splash root=/dev/sda1\n " ) ;
512
- entry. add_cmdline ( "root=/dev/sda2" ) ;
530
+ entry. add_cmdline ( & param ( "root=/dev/sda2" ) ) ;
513
531
514
532
assert_eq ! ( entry. lines. len( ) , 2 ) ;
515
533
assert_eq ! ( entry. lines[ 1 ] , "options quiet splash root=/dev/sda2" ) ;
@@ -518,20 +536,20 @@ mod tests {
518
536
#[ test]
519
537
fn test_add_cmdline_replace_existing_key_only ( ) {
520
538
let mut entry = BootLoaderEntryFile :: new ( "title Test Entry\n options quiet rw splash\n " ) ;
521
- entry. add_cmdline ( "rw" ) ; // Same key, should replace itself (no-op in this case)
539
+ entry. add_cmdline ( & param ( "rw" ) ) ; // Same key, should replace itself (no-op in this case)
522
540
523
541
assert_eq ! ( entry. lines. len( ) , 2 ) ;
524
542
assert_eq ! ( entry. lines[ 1 ] , "options quiet rw splash" ) ;
525
543
526
544
// Test replacing with different key
527
- entry. add_cmdline ( "ro" ) ;
545
+ entry. add_cmdline ( & param ( "ro" ) ) ;
528
546
assert_eq ! ( entry. lines[ 1 ] , "options quiet rw splash ro" ) ;
529
547
}
530
548
531
549
#[ test]
532
550
fn test_add_cmdline_key_with_equals ( ) {
533
551
let mut entry = BootLoaderEntryFile :: new ( "title Test Entry\n options quiet\n " ) ;
534
- entry. add_cmdline ( "composefs=abc123" ) ;
552
+ entry. add_cmdline ( & param ( "composefs=abc123" ) ) ;
535
553
536
554
assert_eq ! ( entry. lines. len( ) , 2 ) ;
537
555
assert_eq ! ( entry. lines[ 1 ] , "options quiet composefs=abc123" ) ;
@@ -541,7 +559,7 @@ mod tests {
541
559
fn test_add_cmdline_replace_key_with_equals ( ) {
542
560
let mut entry =
543
561
BootLoaderEntryFile :: new ( "title Test Entry\n options quiet composefs=old123\n " ) ;
544
- entry. add_cmdline ( "composefs=new456" ) ;
562
+ entry. add_cmdline ( & param ( "composefs=new456" ) ) ;
545
563
546
564
assert_eq ! ( entry. lines. len( ) , 2 ) ;
547
565
assert_eq ! ( entry. lines[ 1 ] , "options quiet composefs=new456" ) ;
@@ -550,26 +568,33 @@ mod tests {
550
568
#[ test]
551
569
fn test_adjust_cmdline_with_composefs ( ) {
552
570
let mut entry = BootLoaderEntryFile :: new ( "title Test Entry\n linux /vmlinuz\n " ) ;
553
- entry. adjust_cmdline ( Some ( "abc123" ) , false , & [ "quiet" , "splash" ] ) ;
571
+ entry. adjust_cmdline ( Some ( & sha256 ( ) ) , false , & params ( & [ "quiet" , "splash" ] ) ) ;
554
572
555
573
assert_eq ! ( entry. lines. len( ) , 3 ) ;
556
- assert_eq ! ( entry. lines[ 2 ] , "options composefs=abc123 quiet splash" ) ;
574
+ assert_eq ! (
575
+ entry. lines[ 2 ] ,
576
+ format!( "options composefs={} quiet splash" , sha256str( ) )
577
+ ) ;
557
578
}
558
579
559
580
#[ test]
560
581
fn test_adjust_cmdline_with_composefs_insecure ( ) {
561
582
let mut entry = BootLoaderEntryFile :: new ( "title Test Entry\n linux /vmlinuz\n " ) ;
562
- entry. adjust_cmdline ( Some ( "abc123" ) , true , & [ ] ) ;
583
+ entry. adjust_cmdline ( Some ( & sha256 ( ) ) , true , & [ ] ) ;
563
584
564
585
assert_eq ! ( entry. lines. len( ) , 3 ) ;
565
586
// Assuming make_cmdline_composefs adds digest=off for insecure mode
566
- assert ! ( entry. lines[ 2 ] . contains( "abc123" ) ) ;
587
+ assert ! ( entry. lines[ 2 ] . contains( & sha256str ( ) ) ) ;
567
588
}
568
589
569
590
#[ test]
570
591
fn test_adjust_cmdline_no_composefs ( ) {
571
592
let mut entry = BootLoaderEntryFile :: new ( "title Test Entry\n linux /vmlinuz\n " ) ;
572
- entry. adjust_cmdline ( None , false , & [ "quiet" , "splash" ] ) ;
593
+ entry. adjust_cmdline (
594
+ None :: < & Sha256HashValue > ,
595
+ false ,
596
+ & params ( & [ "quiet" , "splash" ] ) ,
597
+ ) ;
573
598
574
599
assert_eq ! ( entry. lines. len( ) , 3 ) ;
575
600
assert_eq ! ( entry. lines[ 2 ] , "options quiet splash" ) ;
@@ -578,11 +603,11 @@ mod tests {
578
603
#[ test]
579
604
fn test_adjust_cmdline_existing_options ( ) {
580
605
let mut entry = BootLoaderEntryFile :: new ( "title Test Entry\n options root=/dev/sda1\n " ) ;
581
- entry. adjust_cmdline ( Some ( "abc123" ) , false , & [ "quiet" ] ) ;
606
+ entry. adjust_cmdline ( Some ( & sha256 ( ) ) , false , & params ( & [ "quiet" ] ) ) ;
582
607
583
608
assert_eq ! ( entry. lines. len( ) , 2 ) ;
584
609
assert ! ( entry. lines[ 1 ] . contains( "root=/dev/sda1" ) ) ;
585
- assert ! ( entry. lines[ 1 ] . contains( "abc123" ) ) ;
610
+ assert ! ( entry. lines[ 1 ] . contains( & sha256str ( ) ) ) ;
586
611
assert ! ( entry. lines[ 1 ] . contains( "quiet" ) ) ;
587
612
}
588
613
0 commit comments