Skip to content

Upstream: disallow empty path in proxy_store and friends. #344

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Nov 25, 2024

Conversation

pluknet
Copy link
Contributor

@pluknet pluknet commented Nov 21, 2024

Renaming a temporary file to an empty path ("") returns NGX_ENOPATH with a subsequent ngx_create_full_path() to create the full path. This function skips initial bytes as part of path separator lookup, which causes out of bounds access on short strings.

The fix is to avoid renaming a temporary file to an obviously invalid path, as well as explicitly forbid such syntax for literal values.

Although Coverity reports about potential type underflow, it is not actually possible because the terminating '\0' is always included.

Notably, the run-time check is sufficient enough for Win32 as well. Other short invalid values result either in NGX_ENOENT or NGX_EEXIST and "MoveFile() .. failed" critical log messages, which involves a separate error handling.

Prodded by Coverity (CID 1605485).

Renaming a temporary file to an empty path ("") returns NGX_ENOPATH
with a subsequent ngx_create_full_path() to create the full path.
This function skips initial bytes as part of path separator lookup,
which causes out of bounds access on short strings.

The fix is to avoid renaming a temporary file to an obviously invalid
path, as well as explicitly forbid such syntax for literal values.

Although Coverity reports about potential type underflow, it is not
actually possible because the terminating '\0' is always included.

Notably, the run-time check is sufficient enough for Win32 as well.
Other short invalid values result either in NGX_ENOENT or NGX_EEXIST
and "MoveFile() .. failed" critical log messages, which involves a
separate error handling.

Prodded by Coverity (CID 1605485).
@pluknet pluknet requested a review from arut November 21, 2024 10:22
@Maryna-f5 Maryna-f5 added this to the nginx-1.27.3 milestone Nov 21, 2024
Copy link
Contributor

@arut arut left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Notably, the run-time check is sufficient enough for Win32 as well. Other short invalid values result either in NGX_ENOENT or NGX_EEXIST and "MoveFile() .. failed" critical log messages, which involves a separate error handling.

Which run-time check do you mean? Seems like ngx_create_full_path() does not have any protection against empty/short strings.

@pluknet
Copy link
Contributor Author

pluknet commented Nov 25, 2024

Notably, the run-time check is sufficient enough for Win32 as well. Other short invalid values result either in NGX_ENOENT or NGX_EEXIST and "MoveFile() .. failed" critical log messages, which involves a separate error handling.

Which run-time check do you mean? Seems like ngx_create_full_path() does not have any protection against empty/short strings.

The newly added one, to mitigate ngx_ext_rename_file() call with invalid dst (empty) path:

    if (path.len == 0) {
        return;
    }

FWIW, regarding the ngx_create_full_path() function name: while it may seem that it works with absolute paths only, actually it supports relative paths as well, such as when proxy_store is evaluated to a relative path. In either case, it will try to create all non-existing intermediate sub-directories.

It seems the only reason why ngx_create_full_path() skips initial char (or three on win32) is because otherwise it may end up trying to rename something to zero-length string due to temporal path separator replacement with '\0'.

@pluknet
Copy link
Contributor Author

pluknet commented Nov 25, 2024

Seems like ngx_create_full_path() does not have any protection against empty/short strings.

WRT why ngx_create_full_path() should not be fixed instead:

  • it is only called from the ngx_ext_rename_file() error handling for NGX_ENOPATH and actually I think it should be made static as an inner part of ext rename.
  • other ngx_ext_rename_file() callers use it either with ngx_http_map_uri_to_path() or ngx_http_file_cache_name (http cache) which don't produce empty strings.

Copy link
Contributor

@arut arut left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The patch looks good.

Overall, calling ngx_create_full_path() for something that may not be a full path deserves another look later.

@pluknet
Copy link
Contributor Author

pluknet commented Nov 25, 2024

The patch looks good.

Overall, calling ngx_create_full_path() for something that may not be a full path deserves another look later.

Well, it certainly doesn't work with relative paths on win32 (although it can make you think that it does).

@pluknet pluknet merged commit a448dd5 into nginx:master Nov 25, 2024
1 check passed
@pluknet pluknet deleted the store branch November 25, 2024 13:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants