@@ -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
@@ -397,6 +427,7 @@ impl VmmRpc for RpcHandler {
397427 }
398428
399429 async fn shutdown_vm ( self , request : Id ) -> Result < ( ) > {
430+ check_path_traversal ( & request. id ) ?;
400431 self . guest_agent_client ( & request. id ) ?. shutdown ( ) . await ?;
401432 Ok ( ( ) )
402433 }
@@ -463,21 +494,28 @@ impl VmmRpc for RpcHandler {
463494 }
464495
465496 async fn backup_disk ( self , request : BackupDiskRequest ) -> Result < ( ) > {
497+ check_path_traversal ( & request. vm_id ) ?;
466498 self . app . backup_disk ( & request. vm_id , & request. level ) . await
467499 }
468500
469- async fn list_backups ( self , request : Id ) -> Result < rpc:: ListBackupsResponse > {
470- let backups = self . app . list_backups ( & request. id ) . await ?;
501+ async fn list_backups ( self , request : BackupDiskRequest ) -> Result < rpc:: ListBackupsResponse > {
502+ check_path_traversal ( & request. vm_id ) ?;
503+ let backups = self . app . list_backups ( & request. vm_id ) . await ?;
471504 Ok ( rpc:: ListBackupsResponse { backups } )
472505 }
473506
474507 async fn delete_backup ( self , request : DeleteBackupRequest ) -> Result < ( ) > {
508+ check_path_traversal ( & request. vm_id ) ?;
509+ check_path_traversal ( & request. backup_id ) ?;
475510 self . app
476511 . delete_backup ( & request. vm_id , & request. backup_id )
477512 . await
478513 }
479514
480515 async fn restore_backup ( self , request : RestoreBackupRequest ) -> Result < ( ) > {
516+ check_path_traversal ( & request. vm_id ) ?;
517+ check_path_traversal ( & request. backup_id ) ?;
518+ check_path_traversal ( & request. snapshot_id ) ?;
481519 self . app
482520 . restore_backup ( & request. vm_id , & request. backup_id , & request. snapshot_id )
483521 . await
0 commit comments