@@ -328,19 +328,24 @@ handle_op(?SSH_FXP_INIT, Version, B, State) when is_binary(B) ->
328328 ssh_xfer :xf_send_reply (XF1 , ? SSH_FXP_VERSION , <<? UINT32 (Vsn )>>),
329329 State # state {xf = XF1 };
330330handle_op (? SSH_FXP_REALPATH , ReqId ,
331- <<? UINT32 (RLen ), RPath :RLen /binary >>,
332- State0 ) ->
331+ <<? UINT32 (RLen ), RPath :RLen /binary >>,
332+ State0 ) ->
333333 RelPath = relate_file_name (RPath , State0 , _Canonicalize = false ),
334- {Res , State } = resolve_symlinks (RelPath , State0 ),
334+ {Res , # state { root = Root } = State } = resolve_symlinks (RelPath , State0 ),
335335 case Res of
336- {ok , AbsPath } ->
337- NewAbsPath = chroot_filename (AbsPath , State ),
338- XF = State # state .xf ,
339- Attr = # ssh_xfer_attr {type = directory },
340- ssh_xfer :xf_send_name (XF , ReqId , NewAbsPath , Attr ),
341- State ;
342- {error , _ } = Error ->
343- send_status (Error , ReqId , State )
336+ {ok , AbsPath } ->
337+ case Root =:= " " orelse is_within_root (Root , AbsPath ) of
338+ true ->
339+ NewAbsPath = chroot_filename (AbsPath , State ),
340+ XF = State # state .xf ,
341+ Attr = # ssh_xfer_attr {type = directory },
342+ ssh_xfer :xf_send_name (XF , ReqId , NewAbsPath , Attr ),
343+ State ;
344+ false ->
345+ send_status ({error , enoent }, ReqId , State )
346+ end ;
347+ {error , _ } = Error ->
348+ send_status (Error , ReqId , State )
344349 end ;
345350handle_op (? SSH_FXP_OPENDIR , ReqId ,
346351 <<? UINT32 (RLen ), RPath :RLen /binary >>,
0 commit comments