11#[ macro_use]
22extern crate log;
33
4+ use base64:: prelude:: * ;
45use crossbeam_channel:: unbounded;
56#[ cfg( feature = "blk" ) ]
67use devices:: virtio:: block:: ImageType ;
@@ -1190,6 +1191,24 @@ unsafe fn collapse_str_array(array: &[*const c_char]) -> Result<String, std::str
11901191 Ok ( strvec. join ( " " ) )
11911192}
11921193
1194+ // unlike collapse_str_array, this doesn't do the UTF-8 conversion
1195+ // and just keeps the null-terminated strings as raw bytes
1196+ unsafe fn flatten_cstr_array ( array : & [ * const c_char ] ) -> Vec < u8 > {
1197+ let mut bytevec = Vec :: new ( ) ;
1198+
1199+ for item in array. iter ( ) . take ( MAX_ARGS ) {
1200+ if item. is_null ( ) {
1201+ break ;
1202+ } else {
1203+ let cs = CStr :: from_ptr ( * item) ;
1204+ bytevec. extend_from_slice ( cs. to_bytes ( ) ) ;
1205+ bytevec. push ( 0 ) ;
1206+ }
1207+ }
1208+
1209+ bytevec
1210+ }
1211+
11931212#[ allow( clippy:: format_collect) ]
11941213#[ allow( clippy:: missing_safety_doc) ]
11951214#[ no_mangle]
@@ -1220,7 +1239,14 @@ pub unsafe extern "C" fn krun_set_exec(
12201239 "" . to_string ( )
12211240 } ;
12221241
1223- let env = if !c_envp. is_null ( ) {
1242+ let args_raw = if !c_argv. is_null ( ) {
1243+ let argv_array: & [ * const c_char ] = slice:: from_raw_parts ( c_argv, MAX_ARGS ) ;
1244+ flatten_cstr_array ( argv_array)
1245+ } else {
1246+ vec ! [ ]
1247+ } ;
1248+
1249+ let mut env = if !c_envp. is_null ( ) {
12241250 let envp_array: & [ * const c_char ] = slice:: from_raw_parts ( c_envp, MAX_ARGS ) ;
12251251 match collapse_str_array ( envp_array) {
12261252 Ok ( s) => s,
@@ -1235,6 +1261,11 @@ pub unsafe extern "C" fn krun_set_exec(
12351261 . collect ( )
12361262 } ;
12371263
1264+ // KRUN_INIT_ARGVXX="<base64>" must have at most 128 bytes (KENV_MVALLEN on FreeBSD)
1265+ for ( i, args_part) in args_raw. chunks ( 78 ) . enumerate ( ) {
1266+ env += & format ! ( " KRUN_INIT_ARGV{}={}" , i, BASE64_STANDARD . encode( args_part) ) ;
1267+ }
1268+
12381269 match CTX_MAP . lock ( ) . unwrap ( ) . entry ( ctx_id) {
12391270 Entry :: Occupied ( mut ctx_cfg) => {
12401271 let cfg = ctx_cfg. get_mut ( ) ;
0 commit comments