11#[ macro_use]
22extern crate log;
33
4+ use base64:: prelude:: * ;
45use crossbeam_channel:: unbounded;
56#[ cfg( feature = "blk" ) ]
67use devices:: virtio:: block:: { ImageType , SyncMode } ;
@@ -1278,6 +1279,24 @@ unsafe fn collapse_str_array(array: &[*const c_char]) -> Result<String, std::str
12781279 Ok ( strvec. join ( " " ) )
12791280}
12801281
1282+ // unlike collapse_str_array, this doesn't do the UTF-8 conversion
1283+ // and just keeps the null-terminated strings as raw bytes
1284+ unsafe fn flatten_cstr_array ( array : & [ * const c_char ] ) -> Vec < u8 > {
1285+ let mut bytevec = Vec :: new ( ) ;
1286+
1287+ for item in array. iter ( ) . take ( MAX_ARGS ) {
1288+ if item. is_null ( ) {
1289+ break ;
1290+ } else {
1291+ let cs = CStr :: from_ptr ( * item) ;
1292+ bytevec. extend_from_slice ( cs. to_bytes ( ) ) ;
1293+ bytevec. push ( 0 ) ;
1294+ }
1295+ }
1296+
1297+ bytevec
1298+ }
1299+
12811300#[ allow( clippy:: format_collect) ]
12821301#[ allow( clippy:: missing_safety_doc) ]
12831302#[ no_mangle]
@@ -1308,7 +1327,14 @@ pub unsafe extern "C" fn krun_set_exec(
13081327 "" . to_string ( )
13091328 } ;
13101329
1311- let env = if !c_envp. is_null ( ) {
1330+ let args_raw = if !c_argv. is_null ( ) {
1331+ let argv_array: & [ * const c_char ] = slice:: from_raw_parts ( c_argv, MAX_ARGS ) ;
1332+ flatten_cstr_array ( argv_array)
1333+ } else {
1334+ vec ! [ ]
1335+ } ;
1336+
1337+ let mut env = if !c_envp. is_null ( ) {
13121338 let envp_array: & [ * const c_char ] = slice:: from_raw_parts ( c_envp, MAX_ARGS ) ;
13131339 match collapse_str_array ( envp_array) {
13141340 Ok ( s) => s,
@@ -1323,6 +1349,11 @@ pub unsafe extern "C" fn krun_set_exec(
13231349 . collect ( )
13241350 } ;
13251351
1352+ // KRUN_INIT_ARGVXX="<base64>" must have at most 128 bytes (KENV_MVALLEN on FreeBSD)
1353+ for ( i, args_part) in args_raw. chunks ( 78 ) . enumerate ( ) {
1354+ env += & format ! ( " KRUN_INIT_ARGV{}={}" , i, BASE64_STANDARD . encode( args_part) ) ;
1355+ }
1356+
13261357 match CTX_MAP . lock ( ) . unwrap ( ) . entry ( ctx_id) {
13271358 Entry :: Occupied ( mut ctx_cfg) => {
13281359 let cfg = ctx_cfg. get_mut ( ) ;
0 commit comments