Unverified Commit 0850b172 by Edward Thomson Committed by GitHub

Merge pull request #5950 from boretrk/posixtest

open: input validation for empty segments in path
parents cc4f8bc6 4584660e
...@@ -91,7 +91,7 @@ jobs: ...@@ -91,7 +91,7 @@ jobs:
env: env:
CC: gcc CC: gcc
CMAKE_GENERATOR: Ninja CMAKE_GENERATOR: Ninja
CMAKE_OPTIONS: -DUSE_HTTPS=OpenSSL -DREGEX_BACKEND=builtin -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=valgrind -DUSE_GSSAPI=ON -DDEBUG_STRICT_ALLOC=ON CMAKE_OPTIONS: -DUSE_HTTPS=OpenSSL -DREGEX_BACKEND=builtin -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=valgrind -DUSE_GSSAPI=ON -DDEBUG_STRICT_ALLOC=ON -DDEBUG_STRICT_OPEN=ON
os: ubuntu-latest os: ubuntu-latest
- # Xenial, GCC, mbedTLS - # Xenial, GCC, mbedTLS
container: container:
......
...@@ -51,6 +51,7 @@ OPTION(USE_STANDALONE_FUZZERS "Enable standalone fuzzers (compatible with gcc)" ...@@ -51,6 +51,7 @@ OPTION(USE_STANDALONE_FUZZERS "Enable standalone fuzzers (compatible with gcc)"
OPTION(USE_LEAK_CHECKER "Run tests with leak checker" OFF) OPTION(USE_LEAK_CHECKER "Run tests with leak checker" OFF)
OPTION(DEBUG_POOL "Enable debug pool allocator" OFF) OPTION(DEBUG_POOL "Enable debug pool allocator" OFF)
OPTION(DEBUG_STRICT_ALLOC "Enable strict allocator behavior" OFF) OPTION(DEBUG_STRICT_ALLOC "Enable strict allocator behavior" OFF)
OPTION(DEBUG_STRICT_OPEN "Enable path validation in open" OFF)
OPTION(ENABLE_WERROR "Enable compilation with -Werror" OFF) OPTION(ENABLE_WERROR "Enable compilation with -Werror" OFF)
OPTION(USE_BUNDLED_ZLIB "Use the bundled version of zlib. Can be set to one of Bundled(ON)/Chromium. The Chromium option requires a x86_64 processor with SSE4.2 and CLMUL" OFF) OPTION(USE_BUNDLED_ZLIB "Use the bundled version of zlib. Can be set to one of Bundled(ON)/Chromium. The Chromium option requires a x86_64 processor with SSE4.2 and CLMUL" OFF)
SET(USE_HTTP_PARSER "" CACHE STRING "Specifies the HTTP Parser implementation; either system or builtin.") SET(USE_HTTP_PARSER "" CACHE STRING "Specifies the HTTP Parser implementation; either system or builtin.")
......
...@@ -11,6 +11,11 @@ IF(DEBUG_STRICT_ALLOC) ...@@ -11,6 +11,11 @@ IF(DEBUG_STRICT_ALLOC)
ENDIF() ENDIF()
ADD_FEATURE_INFO(debugalloc GIT_DEBUG_STRICT_ALLOC "debug strict allocators") ADD_FEATURE_INFO(debugalloc GIT_DEBUG_STRICT_ALLOC "debug strict allocators")
IF(DEBUG_STRICT_OPEN)
SET(GIT_DEBUG_STRICT_OPEN 1)
ENDIF()
ADD_FEATURE_INFO(debugopen GIT_DEBUG_STRICT_OPEN "path validation in open")
INCLUDE(PkgBuildConfig) INCLUDE(PkgBuildConfig)
INCLUDE(SanitizeBool) INCLUDE(SanitizeBool)
......
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
#cmakedefine GIT_DEBUG_POOL 1 #cmakedefine GIT_DEBUG_POOL 1
#cmakedefine GIT_DEBUG_STRICT_ALLOC 1 #cmakedefine GIT_DEBUG_STRICT_ALLOC 1
#cmakedefine GIT_DEBUG_STRICT_OPEN 1
#cmakedefine GIT_TRACE 1 #cmakedefine GIT_TRACE 1
#cmakedefine GIT_THREADS 1 #cmakedefine GIT_THREADS 1
......
...@@ -109,6 +109,13 @@ int p_open(const char *path, volatile int flags, ...) ...@@ -109,6 +109,13 @@ int p_open(const char *path, volatile int flags, ...)
{ {
mode_t mode = 0; mode_t mode = 0;
#ifdef GIT_DEBUG_STRICT_OPEN
if (strstr(path, "//") != NULL) {
errno = EACCES;
return -1;
}
#endif
if (flags & O_CREAT) { if (flags & O_CREAT) {
va_list arg_list; va_list arg_list;
......
...@@ -578,7 +578,7 @@ static int iter_load_loose_paths(refdb_fs_backend *backend, refdb_fs_iter *iter) ...@@ -578,7 +578,7 @@ static int iter_load_loose_paths(refdb_fs_backend *backend, refdb_fs_iter *iter)
} }
} }
if ((error = git_buf_printf(&path, "%s/", backend->commonpath)) < 0 || if ((error = git_buf_puts(&path, backend->commonpath)) < 0 ||
(error = git_buf_put(&path, ref_prefix, ref_prefix_len)) < 0) { (error = git_buf_put(&path, ref_prefix, ref_prefix_len)) < 0) {
git_buf_dispose(&path); git_buf_dispose(&path);
return error; return error;
...@@ -1609,8 +1609,9 @@ static char *setup_namespace(git_repository *repo, const char *in) ...@@ -1609,8 +1609,9 @@ static char *setup_namespace(git_repository *repo, const char *in)
GIT_MKDIR_PATH, NULL) < 0) GIT_MKDIR_PATH, NULL) < 0)
goto done; goto done;
/* Return root of the namespaced gitpath, i.e. without the trailing '/refs' */ /* Return root of the namespaced gitpath, i.e. without the trailing 'refs' */
git_buf_rtruncate_at_char(&path, '/'); git_buf_rtruncate_at_char(&path, '/');
git_buf_putc(&path, '/');
out = git_buf_detach(&path); out = git_buf_detach(&path);
done: done:
......
...@@ -543,6 +543,13 @@ int p_open(const char *path, int flags, ...) ...@@ -543,6 +543,13 @@ int p_open(const char *path, int flags, ...)
mode_t mode = 0; mode_t mode = 0;
struct open_opts opts = {0}; struct open_opts opts = {0};
#ifdef GIT_DEBUG_STRICT_OPEN
if (strstr(path, "//") != NULL) {
errno = EACCES;
return -1;
}
#endif
if (git_win32_path_from_utf8(wpath, path) < 0) if (git_win32_path_from_utf8(wpath, path) < 0)
return -1; return -1;
......
...@@ -43,7 +43,7 @@ int git_worktree_list(git_strarray *wts, git_repository *repo) ...@@ -43,7 +43,7 @@ int git_worktree_list(git_strarray *wts, git_repository *repo)
wts->count = 0; wts->count = 0;
wts->strings = NULL; wts->strings = NULL;
if ((error = git_buf_printf(&path, "%s/worktrees/", repo->commondir)) < 0) if ((error = git_buf_joinpath(&path, repo->commondir, "worktrees/")) < 0)
goto exit; goto exit;
if (!git_path_exists(path.ptr) || git_path_is_empty_dir(path.ptr)) if (!git_path_exists(path.ptr) || git_path_is_empty_dir(path.ptr))
goto exit; goto exit;
...@@ -182,7 +182,7 @@ int git_worktree_lookup(git_worktree **out, git_repository *repo, const char *na ...@@ -182,7 +182,7 @@ int git_worktree_lookup(git_worktree **out, git_repository *repo, const char *na
*out = NULL; *out = NULL;
if ((error = git_buf_printf(&path, "%s/worktrees/%s", repo->commondir, name)) < 0) if ((error = git_buf_join3(&path, '/', repo->commondir, "worktrees", name)) < 0)
goto out; goto out;
if ((error = (open_worktree_dir(out, git_repository_workdir(repo), path.ptr, name))) < 0) if ((error = (open_worktree_dir(out, git_repository_workdir(repo), path.ptr, name))) < 0)
...@@ -592,7 +592,7 @@ int git_worktree_prune(git_worktree *wt, ...@@ -592,7 +592,7 @@ int git_worktree_prune(git_worktree *wt,
} }
/* Delete gitdir in parent repository */ /* Delete gitdir in parent repository */
if ((err = git_buf_printf(&path, "%s/worktrees/%s", wt->commondir_path, wt->name)) < 0) if ((err = git_buf_join3(&path, '/', wt->commondir_path, "worktrees", wt->name)) < 0)
goto out; goto out;
if (!git_path_exists(path.ptr)) if (!git_path_exists(path.ptr))
{ {
......
...@@ -1024,7 +1024,7 @@ static void create_paths(const char *root, int depth) ...@@ -1024,7 +1024,7 @@ static void create_paths(const char *root, int depth)
int i; int i;
cl_git_pass(git_buf_puts(&fullpath, root)); cl_git_pass(git_buf_puts(&fullpath, root));
cl_git_pass(git_buf_putc(&fullpath, '/')); cl_git_pass(git_path_to_dir(&fullpath));
root_len = fullpath.size; root_len = fullpath.size;
......
...@@ -49,7 +49,7 @@ static bool test_file_contents(const char *filename, const char *expected) ...@@ -49,7 +49,7 @@ static bool test_file_contents(const char *filename, const char *expected)
git_buf file_path_buf = GIT_BUF_INIT, file_buf = GIT_BUF_INIT; git_buf file_path_buf = GIT_BUF_INIT, file_buf = GIT_BUF_INIT;
bool equals; bool equals;
git_buf_printf(&file_path_buf, "%s/%s", git_repository_path(repo), filename); git_buf_joinpath(&file_path_buf, git_repository_path(repo), filename);
cl_git_pass(git_futils_readbuffer(&file_buf, file_path_buf.ptr)); cl_git_pass(git_futils_readbuffer(&file_buf, file_path_buf.ptr));
equals = (strcmp(file_buf.ptr, expected) == 0); equals = (strcmp(file_buf.ptr, expected) == 0);
...@@ -64,7 +64,7 @@ static void write_file_contents(const char *filename, const char *output) ...@@ -64,7 +64,7 @@ static void write_file_contents(const char *filename, const char *output)
{ {
git_buf file_path_buf = GIT_BUF_INIT; git_buf file_path_buf = GIT_BUF_INIT;
git_buf_printf(&file_path_buf, "%s/%s", git_repository_path(repo), git_buf_joinpath(&file_path_buf, git_repository_path(repo),
filename); filename);
cl_git_rewritefile(file_path_buf.ptr, output); cl_git_rewritefile(file_path_buf.ptr, output);
......
...@@ -127,7 +127,7 @@ void test_odb_foreach__files_in_objects_dir(void) ...@@ -127,7 +127,7 @@ void test_odb_foreach__files_in_objects_dir(void)
cl_fixture_sandbox("testrepo.git"); cl_fixture_sandbox("testrepo.git");
cl_git_pass(git_repository_open(&repo, "testrepo.git")); cl_git_pass(git_repository_open(&repo, "testrepo.git"));
cl_git_pass(git_buf_printf(&buf, "%s/objects/somefile", git_repository_path(repo))); cl_git_pass(git_buf_joinpath(&buf, git_repository_path(repo), "objects/somefile"));
cl_git_mkfile(buf.ptr, ""); cl_git_mkfile(buf.ptr, "");
git_buf_dispose(&buf); git_buf_dispose(&buf);
......
...@@ -70,9 +70,9 @@ void test_worktree_merge__merge_setup(void) ...@@ -70,9 +70,9 @@ void test_worktree_merge__merge_setup(void)
ours, (const git_annotated_commit **)&theirs, 1)); ours, (const git_annotated_commit **)&theirs, 1));
for (i = 0; i < ARRAY_SIZE(merge_files); i++) { for (i = 0; i < ARRAY_SIZE(merge_files); i++) {
git_buf_clear(&path); cl_git_pass(git_buf_joinpath(&path,
cl_git_pass(git_buf_printf(&path, "%s/%s", fixture.worktree->gitdir,
fixture.worktree->gitdir, merge_files[i])); merge_files[i]));
cl_assert(git_path_exists(path.ptr)); cl_assert(git_path_exists(path.ptr));
} }
......
...@@ -44,8 +44,9 @@ void test_worktree_worktree__list_with_invalid_worktree_dirs(void) ...@@ -44,8 +44,9 @@ void test_worktree_worktree__list_with_invalid_worktree_dirs(void)
git_strarray wts; git_strarray wts;
size_t i, j, len; size_t i, j, len;
cl_git_pass(git_buf_printf(&path, "%s/worktrees/invalid", cl_git_pass(git_buf_joinpath(&path,
fixture.repo->commondir)); fixture.repo->commondir,
"worktrees/invalid"));
cl_git_pass(p_mkdir(path.ptr, 0755)); cl_git_pass(p_mkdir(path.ptr, 0755));
len = path.size; len = path.size;
...@@ -145,9 +146,9 @@ void test_worktree_worktree__open_invalid_commondir(void) ...@@ -145,9 +146,9 @@ void test_worktree_worktree__open_invalid_commondir(void)
git_buf buf = GIT_BUF_INIT, path = GIT_BUF_INIT; git_buf buf = GIT_BUF_INIT, path = GIT_BUF_INIT;
cl_git_pass(git_buf_sets(&buf, "/path/to/nonexistent/commondir")); cl_git_pass(git_buf_sets(&buf, "/path/to/nonexistent/commondir"));
cl_git_pass(git_buf_printf(&path, cl_git_pass(git_buf_joinpath(&path,
"%s/worktrees/testrepo-worktree/commondir", fixture.repo->commondir,
fixture.repo->commondir)); "worktrees/testrepo-worktree/commondir"));
cl_git_pass(git_futils_writebuffer(&buf, path.ptr, O_RDWR, 0644)); cl_git_pass(git_futils_writebuffer(&buf, path.ptr, O_RDWR, 0644));
cl_git_pass(git_worktree_lookup(&wt, fixture.repo, "testrepo-worktree")); cl_git_pass(git_worktree_lookup(&wt, fixture.repo, "testrepo-worktree"));
...@@ -165,9 +166,9 @@ void test_worktree_worktree__open_invalid_gitdir(void) ...@@ -165,9 +166,9 @@ void test_worktree_worktree__open_invalid_gitdir(void)
git_buf buf = GIT_BUF_INIT, path = GIT_BUF_INIT; git_buf buf = GIT_BUF_INIT, path = GIT_BUF_INIT;
cl_git_pass(git_buf_sets(&buf, "/path/to/nonexistent/gitdir")); cl_git_pass(git_buf_sets(&buf, "/path/to/nonexistent/gitdir"));
cl_git_pass(git_buf_printf(&path, cl_git_pass(git_buf_joinpath(&path,
"%s/worktrees/testrepo-worktree/gitdir", fixture.repo->commondir,
fixture.repo->commondir)); "worktrees/testrepo-worktree/gitdir"));
cl_git_pass(git_futils_writebuffer(&buf, path.ptr, O_RDWR, 0644)); cl_git_pass(git_futils_writebuffer(&buf, path.ptr, O_RDWR, 0644));
cl_git_pass(git_worktree_lookup(&wt, fixture.repo, "testrepo-worktree")); cl_git_pass(git_worktree_lookup(&wt, fixture.repo, "testrepo-worktree"));
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment