140 lines
4.0 KiB
Diff
140 lines
4.0 KiB
Diff
|
From 893fa014de0f73337ff4a4c9c531d6789b72f5bf Mon Sep 17 00:00:00 2001
|
||
|
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
|
||
|
Date: Sun, 29 Sep 2013 14:40:58 +0200
|
||
|
Subject: [PATCH] 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>
|
||
|
---
|
||
|
src/shared/util.c | 79 +++++++++++++++++-----------------------------------
|
||
|
src/test/test-util.c | 10 +++++++
|
||
|
2 files changed, 36 insertions(+), 53 deletions(-)
|
||
|
|
||
|
Index: systemd-207/src/shared/util.c
|
||
|
===================================================================
|
||
|
--- systemd-207.orig/src/shared/util.c
|
||
|
+++ systemd-207/src/shared/util.c
|
||
|
@@ -4435,38 +4435,31 @@ int dirent_ensure_type(DIR *d, struct di
|
||
|
}
|
||
|
|
||
|
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)
|
||
|
@@ -4478,11 +4471,9 @@ int get_files_in_directory(const char *p
|
||
|
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;
|
||
|
|
||
|
@@ -4492,43 +4483,25 @@ int get_files_in_directory(const char *p
|
||
|
continue;
|
||
|
|
||
|
if (list) {
|
||
|
- if ((unsigned) r >= n) {
|
||
|
- char **t;
|
||
|
-
|
||
|
- n = MAX(16, 2*r);
|
||
|
- t = realloc(l, sizeof(char*) * n);
|
||
|
- if (!t) {
|
||
|
- r = -ENOMEM;
|
||
|
- goto finish;
|
||
|
- }
|
||
|
-
|
||
|
- l = t;
|
||
|
- }
|
||
|
-
|
||
|
- assert((unsigned) r < n);
|
||
|
-
|
||
|
- l[r] = strdup(de->d_name);
|
||
|
- if (!l[r]) {
|
||
|
- r = -ENOMEM;
|
||
|
- goto finish;
|
||
|
- }
|
||
|
+ /* one extra slot is needed for the terminating NULL */
|
||
|
+ if (!GREEDY_REALLOC(l, bufsize, n + 2))
|
||
|
+ return -ENOMEM;
|
||
|
+
|
||
|
+ l[n] = strdup(de->d_name);
|
||
|
+ if (!l[n])
|
||
|
+ return -ENOMEM;
|
||
|
|
||
|
- l[++r] = NULL;
|
||
|
+ l[++n] = NULL;
|
||
|
} else
|
||
|
- r++;
|
||
|
+ n++;
|
||
|
}
|
||
|
|
||
|
-finish:
|
||
|
- if (d)
|
||
|
- closedir(d);
|
||
|
-
|
||
|
- if (r >= 0) {
|
||
|
- if (list)
|
||
|
- *list = l;
|
||
|
- } else
|
||
|
- strv_free(l);
|
||
|
+ if (list) {
|
||
|
+ *list = l;
|
||
|
+ l = NULL; /* avoid freeing */
|
||
|
+ }
|
||
|
|
||
|
- return r;
|
||
|
+ return n;
|
||
|
}
|
||
|
|
||
|
char *strjoin(const char *x, ...) {
|