@@ -9,7 +9,7 @@ use composefs::{
99 tree:: { Directory , FileSystem , ImageError , Inode , LeafContent , RegularFile } ,
1010} ;
1111
12- use crate :: cmdline:: { make_cmdline_composefs , split_cmdline } ;
12+ use crate :: cmdline:: { Cmdline , Parameter } ;
1313
1414/// Strips the key (if it matches) plus the following whitespace from a single line in a "Type #1
1515/// Boot Loader Specification Entry" file.
@@ -65,30 +65,17 @@ impl BootLoaderEntryFile {
6565 ///
6666 /// arg can be something like "composefs=xyz" but it can also be something like "rw". In
6767 /// 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 ) {
7469 // There are three possible paths in this function:
7570 // 1. options line with key= already in it (replace it)
7671 // 2. options line with no key= in it (append key=value)
7772 // 3. no options line (append the entire thing)
7873 for line in & mut self . lines {
7974 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) ;
9177
78+ * line = format ! ( "options {cmdline}" ) ;
9279 return ;
9380 }
9481 }
@@ -99,9 +86,21 @@ impl BootLoaderEntryFile {
9986
10087 /// Adjusts the kernel command-line arguments by adding a composefs= parameter (if appropriate)
10188 /// 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+ ) {
10395 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) ;
105104 }
106105
107106 for item in extra {
@@ -400,8 +399,27 @@ pub fn get_boot_resources<ObjectID: FsVerityHashValue>(
400399
401400#[ cfg( test) ]
402401mod tests {
402+ use composefs:: fsverity:: Sha256HashValue ;
403+ use zerocopy:: FromZeros ;
404+
403405 use super :: * ;
404406
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+
405423 #[ test]
406424 fn test_bootloader_entry_file_new ( ) {
407425 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 {
490508 #[ test]
491509 fn test_add_cmdline_new_options_line ( ) {
492510 let mut entry = BootLoaderEntryFile :: new ( "title Test Entry\n linux /vmlinuz\n " ) ;
493- entry. add_cmdline ( "quiet" ) ;
511+ entry. add_cmdline ( & param ( "quiet" ) ) ;
494512
495513 assert_eq ! ( entry. lines. len( ) , 3 ) ;
496514 assert_eq ! ( entry. lines[ 2 ] , "options quiet" ) ;
@@ -499,7 +517,7 @@ mod tests {
499517 #[ test]
500518 fn test_add_cmdline_append_to_existing_options ( ) {
501519 let mut entry = BootLoaderEntryFile :: new ( "title Test Entry\n options splash\n " ) ;
502- entry. add_cmdline ( "quiet" ) ;
520+ entry. add_cmdline ( & param ( "quiet" ) ) ;
503521
504522 assert_eq ! ( entry. lines. len( ) , 2 ) ;
505523 assert_eq ! ( entry. lines[ 1 ] , "options splash quiet" ) ;
@@ -509,7 +527,7 @@ mod tests {
509527 fn test_add_cmdline_replace_existing_key_value ( ) {
510528 let mut entry =
511529 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" ) ) ;
513531
514532 assert_eq ! ( entry. lines. len( ) , 2 ) ;
515533 assert_eq ! ( entry. lines[ 1 ] , "options quiet splash root=/dev/sda2" ) ;
@@ -518,20 +536,20 @@ mod tests {
518536 #[ test]
519537 fn test_add_cmdline_replace_existing_key_only ( ) {
520538 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)
522540
523541 assert_eq ! ( entry. lines. len( ) , 2 ) ;
524542 assert_eq ! ( entry. lines[ 1 ] , "options quiet rw splash" ) ;
525543
526544 // Test replacing with different key
527- entry. add_cmdline ( "ro" ) ;
545+ entry. add_cmdline ( & param ( "ro" ) ) ;
528546 assert_eq ! ( entry. lines[ 1 ] , "options quiet rw splash ro" ) ;
529547 }
530548
531549 #[ test]
532550 fn test_add_cmdline_key_with_equals ( ) {
533551 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" ) ) ;
535553
536554 assert_eq ! ( entry. lines. len( ) , 2 ) ;
537555 assert_eq ! ( entry. lines[ 1 ] , "options quiet composefs=abc123" ) ;
@@ -541,7 +559,7 @@ mod tests {
541559 fn test_add_cmdline_replace_key_with_equals ( ) {
542560 let mut entry =
543561 BootLoaderEntryFile :: new ( "title Test Entry\n options quiet composefs=old123\n " ) ;
544- entry. add_cmdline ( "composefs=new456" ) ;
562+ entry. add_cmdline ( & param ( "composefs=new456" ) ) ;
545563
546564 assert_eq ! ( entry. lines. len( ) , 2 ) ;
547565 assert_eq ! ( entry. lines[ 1 ] , "options quiet composefs=new456" ) ;
@@ -550,26 +568,33 @@ mod tests {
550568 #[ test]
551569 fn test_adjust_cmdline_with_composefs ( ) {
552570 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" ] ) ) ;
554572
555573 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+ ) ;
557578 }
558579
559580 #[ test]
560581 fn test_adjust_cmdline_with_composefs_insecure ( ) {
561582 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 , & [ ] ) ;
563584
564585 assert_eq ! ( entry. lines. len( ) , 3 ) ;
565586 // Assuming make_cmdline_composefs adds digest=off for insecure mode
566- assert ! ( entry. lines[ 2 ] . contains( "abc123" ) ) ;
587+ assert ! ( entry. lines[ 2 ] . contains( & sha256str ( ) ) ) ;
567588 }
568589
569590 #[ test]
570591 fn test_adjust_cmdline_no_composefs ( ) {
571592 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+ ) ;
573598
574599 assert_eq ! ( entry. lines. len( ) , 3 ) ;
575600 assert_eq ! ( entry. lines[ 2 ] , "options quiet splash" ) ;
@@ -578,11 +603,11 @@ mod tests {
578603 #[ test]
579604 fn test_adjust_cmdline_existing_options ( ) {
580605 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" ] ) ) ;
582607
583608 assert_eq ! ( entry. lines. len( ) , 2 ) ;
584609 assert ! ( entry. lines[ 1 ] . contains( "root=/dev/sda1" ) ) ;
585- assert ! ( entry. lines[ 1 ] . contains( "abc123" ) ) ;
610+ assert ! ( entry. lines[ 1 ] . contains( & sha256str ( ) ) ) ;
586611 assert ! ( entry. lines[ 1 ] . contains( "quiet" ) ) ;
587612 }
588613
0 commit comments