Skip to content
This repository was archived by the owner on Nov 9, 2017. It is now read-only.

Commit 2f29e0c

Browse files
mhaggergitster
authored andcommitted
entry.c: fix possible buffer overflow in remove_subtree()
remove_subtree() manipulated path in a fixed-size buffer even though the length of the input, let alone the length of entries within the directory, were not known in advance. Change the function to take a strbuf argument and use that object as its scratch space. Signed-off-by: Michael Haggerty <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent f63272a commit 2f29e0c

File tree

1 file changed

+17
-17
lines changed

1 file changed

+17
-17
lines changed

entry.c

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -44,33 +44,33 @@ static void create_directories(const char *path, int path_len,
4444
free(buf);
4545
}
4646

47-
static void remove_subtree(const char *path)
47+
static void remove_subtree(struct strbuf *path)
4848
{
49-
DIR *dir = opendir(path);
49+
DIR *dir = opendir(path->buf);
5050
struct dirent *de;
51-
char pathbuf[PATH_MAX];
52-
char *name;
51+
int origlen = path->len;
5352

5453
if (!dir)
55-
die_errno("cannot opendir '%s'", path);
56-
strcpy(pathbuf, path);
57-
name = pathbuf + strlen(path);
58-
*name++ = '/';
54+
die_errno("cannot opendir '%s'", path->buf);
5955
while ((de = readdir(dir)) != NULL) {
6056
struct stat st;
57+
6158
if (is_dot_or_dotdot(de->d_name))
6259
continue;
63-
strcpy(name, de->d_name);
64-
if (lstat(pathbuf, &st))
65-
die_errno("cannot lstat '%s'", pathbuf);
60+
61+
strbuf_addch(path, '/');
62+
strbuf_addstr(path, de->d_name);
63+
if (lstat(path->buf, &st))
64+
die_errno("cannot lstat '%s'", path->buf);
6665
if (S_ISDIR(st.st_mode))
67-
remove_subtree(pathbuf);
68-
else if (unlink(pathbuf))
69-
die_errno("cannot unlink '%s'", pathbuf);
66+
remove_subtree(path);
67+
else if (unlink(path->buf))
68+
die_errno("cannot unlink '%s'", path->buf);
69+
strbuf_setlen(path, origlen);
7070
}
7171
closedir(dir);
72-
if (rmdir(path))
73-
die_errno("cannot rmdir '%s'", path);
72+
if (rmdir(path->buf))
73+
die_errno("cannot rmdir '%s'", path->buf);
7474
}
7575

7676
static int create_file(const char *path, unsigned int mode)
@@ -271,7 +271,7 @@ int checkout_entry(struct cache_entry *ce,
271271
return 0;
272272
if (!state->force)
273273
return error("%s is a directory", path.buf);
274-
remove_subtree(path.buf);
274+
remove_subtree(&path);
275275
} else if (unlink(path.buf))
276276
return error("unable to unlink old '%s' (%s)",
277277
path.buf, strerror(errno));

0 commit comments

Comments
 (0)