summaryrefslogtreecommitdiff
path: root/src/shared/util.c
diff options
context:
space:
mode:
authorAnthony G. Basile <blueness@gentoo.org>2014-12-20 10:00:36 -0500
committerAnthony G. Basile <blueness@gentoo.org>2014-12-20 10:00:36 -0500
commitc74cee5a9bf6cbf033d230a448cf606e910a3a9b (patch)
treebbc268958b6b6e686323ffab48233d28452e4416 /src/shared/util.c
parent4ccd9baa59b24ae700ccf39e01dbf36214e48a5f (diff)
src/shared/util.c: fix tempfn_xxxxxx()
Signed-off-by: Anthony G. Basile <blueness@gentoo.org>
Diffstat (limited to 'src/shared/util.c')
-rw-r--r--src/shared/util.c37
1 files changed, 29 insertions, 8 deletions
diff --git a/src/shared/util.c b/src/shared/util.c
index 3fa616b788..5dd2b5b4b3 100644
--- a/src/shared/util.c
+++ b/src/shared/util.c
@@ -1447,6 +1447,26 @@ bool in_initrd(void) {
return saved;
}
+bool filename_is_valid(const char *p) {
+
+ if (isempty(p))
+ return false;
+
+ if (strchr(p, '/'))
+ return false;
+
+ if (streq(p, "."))
+ return false;
+
+ if (streq(p, ".."))
+ return false;
+
+ if (strlen(p) > FILENAME_MAX)
+ return false;
+
+ return true;
+}
+
/* hey glibc, APIs with callbacks without a user pointer are so useless */
void *xbsearch_r(const void *key, const void *base, size_t nmemb, size_t size,
int (*compar) (const void *, const void *, void *), void *arg) {
@@ -1565,16 +1585,12 @@ int mkstemp_safe(char *pattern) {
return fd;
}
-char *tempfn_xxxxxx(const char *p) {
+int tempfn_xxxxxx(const char *p, char **ret) {
const char *fn;
char *t;
- size_t k;
assert(p);
-
- t = new(char, strlen(p) + 1 + 6 + 1);
- if (!t)
- return NULL;
+ assert(ret);
/*
* Turns this:
@@ -1585,9 +1601,14 @@ char *tempfn_xxxxxx(const char *p) {
*/
fn = basename(p);
- k = fn - p;
+ if (!filename_is_valid(fn))
+ return -EINVAL;
+
+ t = new(char, strlen(p) + 1 + 6 + 1);
+ if (!t)
+ return -ENOMEM;
- strcpy(stpcpy(stpcpy(mempcpy(t, p, k), "."), fn), "XXXXXX");
+ strcpy(stpcpy(stpcpy(mempcpy(t, p, fn - p), "."), fn), "XXXXXX");
*ret = path_kill_slashes(t);
return 0;