Skip to content

Commit 0850b17

Browse files
authored
Merge pull request libgit2#5950 from boretrk/posixtest
open: input validation for empty segments in path
2 parents cc4f8bc + 4584660 commit 0850b17

File tree

13 files changed

+44
-21
lines changed

13 files changed

+44
-21
lines changed

.github/workflows/main.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ jobs:
9191
env:
9292
CC: gcc
9393
CMAKE_GENERATOR: Ninja
94-
CMAKE_OPTIONS: -DUSE_HTTPS=OpenSSL -DREGEX_BACKEND=builtin -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=valgrind -DUSE_GSSAPI=ON -DDEBUG_STRICT_ALLOC=ON
94+
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
9595
os: ubuntu-latest
9696
- # Xenial, GCC, mbedTLS
9797
container:

CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ OPTION(USE_STANDALONE_FUZZERS "Enable standalone fuzzers (compatible with gcc)"
5151
OPTION(USE_LEAK_CHECKER "Run tests with leak checker" OFF)
5252
OPTION(DEBUG_POOL "Enable debug pool allocator" OFF)
5353
OPTION(DEBUG_STRICT_ALLOC "Enable strict allocator behavior" OFF)
54+
OPTION(DEBUG_STRICT_OPEN "Enable path validation in open" OFF)
5455
OPTION(ENABLE_WERROR "Enable compilation with -Werror" OFF)
5556
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)
5657
SET(USE_HTTP_PARSER "" CACHE STRING "Specifies the HTTP Parser implementation; either system or builtin.")

src/CMakeLists.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,11 @@ IF(DEBUG_STRICT_ALLOC)
1111
ENDIF()
1212
ADD_FEATURE_INFO(debugalloc GIT_DEBUG_STRICT_ALLOC "debug strict allocators")
1313

14+
IF(DEBUG_STRICT_OPEN)
15+
SET(GIT_DEBUG_STRICT_OPEN 1)
16+
ENDIF()
17+
ADD_FEATURE_INFO(debugopen GIT_DEBUG_STRICT_OPEN "path validation in open")
18+
1419
INCLUDE(PkgBuildConfig)
1520
INCLUDE(SanitizeBool)
1621

src/features.h.in

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
#cmakedefine GIT_DEBUG_POOL 1
55
#cmakedefine GIT_DEBUG_STRICT_ALLOC 1
6+
#cmakedefine GIT_DEBUG_STRICT_OPEN 1
67

78
#cmakedefine GIT_TRACE 1
89
#cmakedefine GIT_THREADS 1

src/posix.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,13 @@ int p_open(const char *path, volatile int flags, ...)
109109
{
110110
mode_t mode = 0;
111111

112+
#ifdef GIT_DEBUG_STRICT_OPEN
113+
if (strstr(path, "//") != NULL) {
114+
errno = EACCES;
115+
return -1;
116+
}
117+
#endif
118+
112119
if (flags & O_CREAT) {
113120
va_list arg_list;
114121

src/refdb_fs.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -578,7 +578,7 @@ static int iter_load_loose_paths(refdb_fs_backend *backend, refdb_fs_iter *iter)
578578
}
579579
}
580580

581-
if ((error = git_buf_printf(&path, "%s/", backend->commonpath)) < 0 ||
581+
if ((error = git_buf_puts(&path, backend->commonpath)) < 0 ||
582582
(error = git_buf_put(&path, ref_prefix, ref_prefix_len)) < 0) {
583583
git_buf_dispose(&path);
584584
return error;
@@ -1609,8 +1609,9 @@ static char *setup_namespace(git_repository *repo, const char *in)
16091609
GIT_MKDIR_PATH, NULL) < 0)
16101610
goto done;
16111611

1612-
/* Return root of the namespaced gitpath, i.e. without the trailing '/refs' */
1612+
/* Return root of the namespaced gitpath, i.e. without the trailing 'refs' */
16131613
git_buf_rtruncate_at_char(&path, '/');
1614+
git_buf_putc(&path, '/');
16141615
out = git_buf_detach(&path);
16151616

16161617
done:

src/win32/posix_w32.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -543,6 +543,13 @@ int p_open(const char *path, int flags, ...)
543543
mode_t mode = 0;
544544
struct open_opts opts = {0};
545545

546+
#ifdef GIT_DEBUG_STRICT_OPEN
547+
if (strstr(path, "//") != NULL) {
548+
errno = EACCES;
549+
return -1;
550+
}
551+
#endif
552+
546553
if (git_win32_path_from_utf8(wpath, path) < 0)
547554
return -1;
548555

src/worktree.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ int git_worktree_list(git_strarray *wts, git_repository *repo)
4343
wts->count = 0;
4444
wts->strings = NULL;
4545

46-
if ((error = git_buf_printf(&path, "%s/worktrees/", repo->commondir)) < 0)
46+
if ((error = git_buf_joinpath(&path, repo->commondir, "worktrees/")) < 0)
4747
goto exit;
4848
if (!git_path_exists(path.ptr) || git_path_is_empty_dir(path.ptr))
4949
goto exit;
@@ -182,7 +182,7 @@ int git_worktree_lookup(git_worktree **out, git_repository *repo, const char *na
182182

183183
*out = NULL;
184184

185-
if ((error = git_buf_printf(&path, "%s/worktrees/%s", repo->commondir, name)) < 0)
185+
if ((error = git_buf_join3(&path, '/', repo->commondir, "worktrees", name)) < 0)
186186
goto out;
187187

188188
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,
592592
}
593593

594594
/* Delete gitdir in parent repository */
595-
if ((err = git_buf_printf(&path, "%s/worktrees/%s", wt->commondir_path, wt->name)) < 0)
595+
if ((err = git_buf_join3(&path, '/', wt->commondir_path, "worktrees", wt->name)) < 0)
596596
goto out;
597597
if (!git_path_exists(path.ptr))
598598
{

tests/iterator/workdir.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1024,7 +1024,7 @@ static void create_paths(const char *root, int depth)
10241024
int i;
10251025

10261026
cl_git_pass(git_buf_puts(&fullpath, root));
1027-
cl_git_pass(git_buf_putc(&fullpath, '/'));
1027+
cl_git_pass(git_path_to_dir(&fullpath));
10281028

10291029
root_len = fullpath.size;
10301030

tests/merge/workdir/setup.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ static bool test_file_contents(const char *filename, const char *expected)
4949
git_buf file_path_buf = GIT_BUF_INIT, file_buf = GIT_BUF_INIT;
5050
bool equals;
5151

52-
git_buf_printf(&file_path_buf, "%s/%s", git_repository_path(repo), filename);
52+
git_buf_joinpath(&file_path_buf, git_repository_path(repo), filename);
5353

5454
cl_git_pass(git_futils_readbuffer(&file_buf, file_path_buf.ptr));
5555
equals = (strcmp(file_buf.ptr, expected) == 0);
@@ -64,7 +64,7 @@ static void write_file_contents(const char *filename, const char *output)
6464
{
6565
git_buf file_path_buf = GIT_BUF_INIT;
6666

67-
git_buf_printf(&file_path_buf, "%s/%s", git_repository_path(repo),
67+
git_buf_joinpath(&file_path_buf, git_repository_path(repo),
6868
filename);
6969
cl_git_rewritefile(file_path_buf.ptr, output);
7070

0 commit comments

Comments
 (0)