Skip to content

Loading…

Sanitize log message #109

Closed
wants to merge 2 commits into from

2 participants

@nicad

Add protection against non string fields being logged. It can happen when using an authorization header with custom scheme (i.e. not handled by YAWS). The user name ends up being the atom undefined and would result into a badarg error from file:write() and also a port error on FreeBSD.

nicad added some commits
@nicad nicad log debug messages to the error_logger given that stdout is not avail…
…able in embedded mode. Default to a tcp queue length backlog of 1024 (instead of 5 git diff)
d75e78a
@nicad nicad make sure to always send proper strings to file:write() while logging…
…, failure to do so on FreeBSD could result into a emulator Bad value on output port 'efile' if bad data makes it there, say an atom
770d123
@vinoski
Collaborator

Got it, thanks for the help.

@vinoski vinoski closed this
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Jun 13, 2012
  1. @nicad

    log debug messages to the error_logger given that stdout is not avail…

    nicad committed
    …able in embedded mode. Default to a tcp queue length backlog of 1024 (instead of 5 git diff)
Commits on Jun 14, 2012
  1. @nicad

    make sure to always send proper strings to file:write() while logging…

    nicad committed
    …, failure to do so on FreeBSD could result into a emulator Bad value on output port 'efile' if bad data makes it there, say an atom
Showing with 35 additions and 14 deletions.
  1. +25 −10 src/yaws_debug.erl
  2. +5 −2 src/yaws_log.erl
  3. +5 −2 src/yaws_server.erl
View
35 src/yaws_debug.erl
@@ -33,7 +33,7 @@ typecheck([{record, Rec, X} | Tail], File, Line) when is_atom(X),
typecheck([{int, Int} |Tail], File, Line) when is_integer(Int) ->
typecheck(Tail, File, Line);
typecheck([Err|_], File, Line) ->
- io:format(user, "TC ERROR ~s:~w:~n~p",
+ debug_format(user, "TC ERROR ~s:~w:~n~p",
[File, Line, Err]),
erlang:error(tcerr);
typecheck([], _,_) ->
@@ -119,11 +119,11 @@ assert(_,_,_,Failure) ->
fail(Failure).
fail({assert,File,Line,Message}) ->
- io:format(user, "Assertion FAILED ~p:~p, pid ~w exiting: ~p~n",
+ debug_format(user, "Assertion FAILED ~p:~p, pid ~w exiting: ~p~n",
[File, Line, self(), Message]),
erlang:error(assertion_failed);
fail({alert,File,Line,Message}) ->
- io:format(user, "Assert WARNING ~p:~p, pid ~w: ~p~n",
+ debug_format(user, "Assert WARNING ~p:~p, pid ~w: ~p~n",
[File, Line, self(), Message]),
ok;
fail({{debug,Fstr}, File,Line,Fmt, Args}) ->
@@ -132,30 +132,45 @@ fail({{debug,Fstr}, File,Line,Fmt, Args}) ->
[Fstr, node(), filename:basename(File),
Line, self()])),
- case (catch io:format(user, Str ++ Fmt ++ "~n", Args)) of
+ case (catch debug_format(user, Str ++ Fmt ++ "~n", Args)) of
ok -> ok;
- _ -> io:format(user, "ERROR ~p:~p: Pid ~w: (bad format)~n~p,~p~n",
+ _ -> debug_format(user, "ERROR ~p:~p: Pid ~w: (bad format)~n~p,~p~n",
[File, Line, self(), Fmt, Args]),
ok
end;
fail({format, File,Line,Fmt,Args}) ->
- case (catch io:format(user, Fmt,Args)) of
+ case (catch debug_format(user, Fmt,Args)) of
ok -> ok;
_ ->
- io:format(user, "ERROR ~p:~p: Pid ~w: (bad format)~n~p,~p~n",
+ debug_format(user, "ERROR ~p:~p: Pid ~w: (bad format)~n~p,~p~n",
[File, Line, self(), Fmt, Args]),
ok
end.
+debug_format(_, F, D) ->
+ debug_format(F, D).
+
+debug_format(F, A) ->
+ Str = case catch io_lib:format("yaws debug: " ++ F, A) of
+ {'EXIT', Reason} ->
+ io_lib:format("yaws debug: F=~s A=~p (failed to format: ~p)",
+ [F, A, Reason]);
+ Ok -> Ok
+ end,
+ error_logger:info_msg(Str),
+ catch io:format(F, A),
+ ok.
+
format(F, A) ->
format(get(gc), F, A).
format(GC, F, A) ->
case ?gc_has_debug(GC) of
true ->
- io:format("yaws:" ++ F, A);
+ error_logger:info_msg("yaws debug:" ++ F, A);
+ %%io:format("yaws:" ++ F, A);
false ->
ok
end.
@@ -184,7 +199,7 @@ mktags() ->
xref([Dir]) ->
- io:format("~p~n", [xref:d(Dir)]),
+ debug_format("~p~n", [xref:d(Dir)]),
init:stop().
@@ -218,7 +233,7 @@ pids() ->
eprof() ->
eprof:start(),
eprof:profile(pids()),
- io:format("Ok run some traffic \n", []).
+ debug_format("Ok run some traffic \n", []).
View
7 src/yaws_log.erl
@@ -316,7 +316,7 @@ handle_cast({_ServerName, access, Fd, {Ip, Req, InH, OutH, _}}, State) ->
Msg = fmt_access_log(State#state.now, fmt_ip(Ip, State), User,
[Meth, $\s, Path, $\s, Ver],
Status, Len, Referer, UserAgent),
- file:write(Fd, Msg),
+ file:write(Fd, safe_log_data(Msg)),
{noreply, State};
false ->
{noreply, State}
@@ -334,7 +334,7 @@ handle_cast({ServerName, auth, Fd, {Ip, Path, Item}}, State) ->
{401, Realm} -> [" 401 realm=", Realm];
{401, User, PWD} -> [" 401 user=", User, " badpwd=", PWD]
end, "\n"],
- file:write(Fd, Msg),
+ file:write(Fd, safe_log_data(Msg)),
{noreply, State};
false ->
{noreply,State}
@@ -489,5 +489,8 @@ left_fill(N, Width, _Fill) when length(N) >= Width ->
left_fill(N, Width, Fill) ->
left_fill([Fill|N], Width, Fill).
+safe_log_data(Elements) ->
+ [ yaws:to_string(E) || E <- Elements ].
+
View
7 src/yaws_server.erl
@@ -864,15 +864,18 @@ listen_opts(SC) ->
true ->
[]
end,
- [binary,
+ Opts = [binary,
{ip, SC#sconf.listen},
{packet, http},
{packet_size, 16#4000},
{recbuf, 8192},
{reuseaddr, true},
+ {backlog, 1024},
{active, false}
| proplists:get_value(listen_opts, SC#sconf.soptions, [])
- ] ++ InetType.
+ ] ++ InetType,
+ ?Debug("listen options: ~p", [Opts]),
+ Opts.
ssl_listen_opts(GC, SC, SSL) ->
InetType = if
Something went wrong with that request. Please try again.