@@ -106,6 +106,30 @@ fn resolve_gpus(gpu_cfg: &rpc::GpuConfig) -> Result<GpuConfig> {
106106 }
107107}
108108
109+ fn check_path_traversal ( input : & str ) -> Result < ( ) > {
110+ if input. is_empty ( ) {
111+ bail ! ( "path is empty" ) ;
112+ }
113+
114+ if input. len ( ) > 255 {
115+ bail ! ( "path is too long" ) ;
116+ }
117+
118+ if input. contains ( '/' ) {
119+ bail ! ( "path contains '/'" ) ;
120+ }
121+
122+ if input. contains ( '\0' ) {
123+ bail ! ( "path contains '\0 '" ) ;
124+ }
125+
126+ if input == "." || input == ".." {
127+ bail ! ( "path is '.' or '..'" ) ;
128+ }
129+
130+ Ok ( ( ) )
131+ }
132+
109133impl RpcHandler {
110134 fn resolve_gpus ( & self , gpu_cfg : & rpc:: GpuConfig ) -> Result < GpuConfig > {
111135 let gpus = resolve_gpus ( gpu_cfg) ?;
@@ -209,6 +233,7 @@ impl VmmRpc for RpcHandler {
209233 }
210234
211235 async fn start_vm ( self , request : Id ) -> Result < ( ) > {
236+ check_path_traversal ( & request. id ) ?;
212237 self . app
213238 . start_vm ( & request. id )
214239 . await
@@ -217,6 +242,7 @@ impl VmmRpc for RpcHandler {
217242 }
218243
219244 async fn stop_vm ( self , request : Id ) -> Result < ( ) > {
245+ check_path_traversal ( & request. id ) ?;
220246 self . app
221247 . stop_vm ( & request. id )
222248 . await
@@ -225,6 +251,7 @@ impl VmmRpc for RpcHandler {
225251 }
226252
227253 async fn remove_vm ( self , request : Id ) -> Result < ( ) > {
254+ check_path_traversal ( & request. id ) ?;
228255 self . app
229256 . remove_vm ( & request. id )
230257 . await
@@ -253,6 +280,7 @@ impl VmmRpc for RpcHandler {
253280 }
254281
255282 async fn upgrade_app ( self , request : UpgradeAppRequest ) -> Result < Id > {
283+ check_path_traversal ( & request. id ) ?;
256284 let new_id = if !request. compose_file . is_empty ( ) {
257285 // check the compose file is valid
258286 let _app_compose: AppCompose =
@@ -322,6 +350,7 @@ impl VmmRpc for RpcHandler {
322350 }
323351
324352 async fn get_info ( self , request : Id ) -> Result < GetInfoResponse > {
353+ check_path_traversal ( & request. id ) ?;
325354 if let Some ( vm) = self . app . vm_info ( & request. id ) . await ? {
326355 Ok ( GetInfoResponse {
327356 found : true ,
@@ -337,6 +366,7 @@ impl VmmRpc for RpcHandler {
337366
338367 #[ tracing:: instrument( skip( self , request) , fields( id = request. id) ) ]
339368 async fn resize_vm ( self , request : ResizeVmRequest ) -> Result < ( ) > {
369+ check_path_traversal ( & request. id ) ?;
340370 info ! ( "Resizing VM: {:?}" , request) ;
341371 let vm = self
342372 . app
@@ -393,6 +423,7 @@ impl VmmRpc for RpcHandler {
393423 }
394424
395425 async fn shutdown_vm ( self , request : Id ) -> Result < ( ) > {
426+ check_path_traversal ( & request. id ) ?;
396427 self . guest_agent_client ( & request. id ) ?. shutdown ( ) . await ?;
397428 Ok ( ( ) )
398429 }
@@ -458,21 +489,28 @@ impl VmmRpc for RpcHandler {
458489 }
459490
460491 async fn backup_disk ( self , request : BackupDiskRequest ) -> Result < ( ) > {
492+ check_path_traversal ( & request. vm_id ) ?;
461493 self . app . backup_disk ( & request. vm_id , & request. level ) . await
462494 }
463495
464- async fn list_backups ( self , request : Id ) -> Result < rpc:: ListBackupsResponse > {
465- let backups = self . app . list_backups ( & request. id ) . await ?;
496+ async fn list_backups ( self , request : BackupDiskRequest ) -> Result < rpc:: ListBackupsResponse > {
497+ check_path_traversal ( & request. vm_id ) ?;
498+ let backups = self . app . list_backups ( & request. vm_id ) . await ?;
466499 Ok ( rpc:: ListBackupsResponse { backups } )
467500 }
468501
469502 async fn delete_backup ( self , request : DeleteBackupRequest ) -> Result < ( ) > {
503+ check_path_traversal ( & request. vm_id ) ?;
504+ check_path_traversal ( & request. backup_id ) ?;
470505 self . app
471506 . delete_backup ( & request. vm_id , & request. backup_id )
472507 . await
473508 }
474509
475510 async fn restore_backup ( self , request : RestoreBackupRequest ) -> Result < ( ) > {
511+ check_path_traversal ( & request. vm_id ) ?;
512+ check_path_traversal ( & request. backup_id ) ?;
513+ check_path_traversal ( & request. snapshot_id ) ?;
476514 self . app
477515 . restore_backup ( & request. vm_id , & request. backup_id , & request. snapshot_id )
478516 . await
0 commit comments