Fix buffer overrun when enumerating files

https://bugs.freedesktop.org/show_bug.cgi?id=69887

Based-on-a-patch-by: Hans Petter Jansson <hpj@copyleft.no>

Conflicts:
	src/test/test-util.c
This commit is contained in:
Zbigniew Jędrzejewski-Szmek
2013-09-29 14:40:58 +02:00
parent 649bbc2c12
commit bbe5efee5e
2 changed files with 28 additions and 53 deletions
+26 -53
View File
@@ -4375,38 +4375,31 @@ int dirent_ensure_type(DIR *d, struct dirent *de) {
}
int in_search_path(const char *path, char **search) {
char **i, *parent;
char **i;
_cleanup_free_ char *parent = NULL;
int r;
r = path_get_parent(path, &parent);
if (r < 0)
return r;
r = 0;
STRV_FOREACH(i, search)
if (path_equal(parent, *i))
return 1;
STRV_FOREACH(i, search) {
if (path_equal(parent, *i)) {
r = 1;
break;
}
}
free(parent);
return r;
return 0;
}
int get_files_in_directory(const char *path, char ***list) {
DIR *d;
int r = 0;
unsigned n = 0;
char **l = NULL;
_cleanup_closedir_ DIR *d = NULL;
size_t bufsize = 0, n = 0;
_cleanup_strv_free_ char **l = NULL;
assert(path);
/* Returns all files in a directory in *list, and the number
* of files as return value. If list is NULL returns only the
* number */
* number. */
d = opendir(path);
if (!d)
@@ -4418,11 +4411,9 @@ int get_files_in_directory(const char *path, char ***list) {
int k;
k = readdir_r(d, &buf.de, &de);
if (k != 0) {
r = -k;
goto finish;
}
assert(k >= 0);
if (k > 0)
return -k;
if (!de)
break;
@@ -4432,43 +4423,25 @@ int get_files_in_directory(const char *path, char ***list) {
continue;
if (list) {
if ((unsigned) r >= n) {
char **t;
/* one extra slot is needed for the terminating NULL */
if (!GREEDY_REALLOC(l, bufsize, n + 2))
return -ENOMEM;
n = MAX(16, 2*r);
t = realloc(l, sizeof(char*) * n);
if (!t) {
r = -ENOMEM;
goto finish;
}
l[n] = strdup(de->d_name);
if (!l[n])
return -ENOMEM;
l = t;
}
assert((unsigned) r < n);
l[r] = strdup(de->d_name);
if (!l[r]) {
r = -ENOMEM;
goto finish;
}
l[++r] = NULL;
l[++n] = NULL;
} else
r++;
n++;
}
finish:
if (d)
closedir(d);
if (list) {
*list = l;
l = NULL; /* avoid freeing */
}
if (r >= 0) {
if (list)
*list = l;
} else
strv_free(l);
return r;
return n;
}
char *strjoin(const char *x, ...) {
+2
View File
@@ -618,6 +618,8 @@ char *strextend(char **x, ...);
char *strrep(const char *s, unsigned n);
void* greedy_realloc(void **p, size_t *allocated, size_t need);
#define GREEDY_REALLOC(array, allocated, need) \
greedy_realloc((void**) &(array), &(allocated), sizeof((array)[0]) * (need))
static inline void _reset_errno_(int *saved_errno) {
errno = *saved_errno;