Pure Erlang implementation of 9p2000 protocol
filesystem fs 9p2000 erlang 9p

Prevent unfs handler from walking out of root directory

hauleth.dev 4ad25702 9f509624

verified
+18 -3
+18 -3
src/e9p_unfs.erl
··· 6 6 7 7 -behaviour(e9p_fs). 8 8 9 - % -include_lib("kernel/include/logger.hrl"). 9 + -include_lib("kernel/include/logger.hrl"). 10 10 -include_lib("kernel/include/file.hrl"). 11 11 12 12 -export([init/1, root/3, walk/3, stat/2, open/3, read/4, clunk/2]). 13 13 14 + -doc """ 15 + Create QID for given path. 16 + """. 14 17 qid(Path) -> 15 18 case file:read_file_info(Path, [{time, posix}]) of 16 19 {ok, #file_info{type = Type, inode = Inode}} -> ··· 19 22 {error, _} = Error -> Error 20 23 end. 21 24 25 + -doc """ 26 + Create QID and Stat data for given path. 27 + """. 22 28 qid_stat(Root, Path) -> 23 29 case file:read_file_info(Path, [{time, posix}]) of 24 30 {ok, #file_info{type = Type, inode = Inode} = FI} -> ··· 29 35 end. 30 36 31 37 init(#{path := Path}) -> 32 - {ok, #{root => Path}}. 38 + {ok, #{root => unicode:characters_to_binary(Path)}}. 33 39 34 - root(_UName, _AName, #{root := Root} = State) -> 40 + root(UName, AName, #{root := Root} = State) -> 41 + ?LOG_INFO(#{uname => UName, aname => AName}), 35 42 maybe 36 43 {ok, Qid} ?= qid(Root), 37 44 {ok, Qid, State} 38 45 end. 39 46 47 + walk(#{state := {Root, _}}, ~"..", #{root := Root} = State) -> 48 + {false, State}; 49 + walk(#{state := {Path, _}}, ~"..", State) -> 50 + Next = filename:dirname(Path), 51 + case qid(Next) of 52 + {ok, NQid} -> {NQid, State}; 53 + {error, _} -> {false, State} 54 + end; 40 55 walk(#{state := {Path, _}}, File, State) -> 41 56 Next = filename:join(Path, File), 42 57 case qid(Next) of