Skip to content

Commit b336838

Browse files
committed
File.mkdir_p: Fix TOCTOU issue & handle errors from parent mkdir
Fix TOCTOU, meaning :file.make_dir returning {:error, :eexists} is now tested without having to trigger a race-condition. Also change dir?() returning false from returning :eexist to :enotdir And handling errors from parent directory creation allows to avoid non-sensical errors like File.mkdir_p returning :enoent instead of :eacces
1 parent 965ee9b commit b336838

File tree

1 file changed

+14
-15
lines changed

1 file changed

+14
-15
lines changed

lib/elixir/lib/file.ex

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -310,24 +310,23 @@ defmodule File do
310310
end
311311

312312
defp do_mkdir_p(path) do
313-
if dir?(path) do
313+
parent = Path.dirname(path)
314+
315+
if parent == path do
314316
:ok
315317
else
316-
parent = Path.dirname(path)
317-
318-
if parent == path do
319-
# Protect against infinite loop
320-
{:error, :einval}
321-
else
322-
_ = do_mkdir_p(parent)
323-
324-
case :file.make_dir(path) do
325-
{:error, :eexist} = error ->
326-
if dir?(path), do: :ok, else: error
318+
case do_mkdir_p(parent) do
319+
:ok ->
320+
case :file.make_dir(path) do
321+
{:error, :eexist} ->
322+
if dir?(path), do: :ok, else: {:error, :enotdir}
323+
324+
other ->
325+
other
326+
end
327327

328-
other ->
329-
other
330-
end
328+
e ->
329+
e
331330
end
332331
end
333332
end

0 commit comments

Comments
 (0)