From: Vladimír Čunát Date: Fri, 4 Sep 2020 17:24:21 +0000 (+0200) Subject: lib/cache: avoid printing relative paths to cache X-Git-Tag: v5.1.3~1^2~4 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b1b57540157940ef082f77fb809be78b6c646ffc;p=thirdparty%2Fknot-resolver.git lib/cache: avoid printing relative paths to cache --- diff --git a/lib/cache/api.c b/lib/cache/api.c index 3e8351fad..d7794eca9 100644 --- a/lib/cache/api.c +++ b/lib/cache/api.c @@ -135,8 +135,8 @@ int kr_cache_open(struct kr_cache *cache, const struct kr_cdb_api *api, struct k ret = cache->api->open(&cache->db, &cache->stats, &opts2, mm); } - char *fpath; - if (asprintf(&fpath, "%s/data.mdb", opts->path) > 0) { + char *fpath = kr_absolutize_path(opts->path, "data.mdb"); + if (fpath) { kr_cache_emergency_file_to_remove = fpath; } else { assert(false); /* non-critical, but still */ diff --git a/lib/cache/cdb_lmdb.c b/lib/cache/cdb_lmdb.c index 3b986df82..b56d8335e 100644 --- a/lib/cache/cdb_lmdb.c +++ b/lib/cache/cdb_lmdb.c @@ -297,7 +297,7 @@ static int cdb_open_env(struct lmdb_env *env, const char *path, const size_t map ret = mdb_env_create(&env->env); if (ret != MDB_SUCCESS) return lmdb_error(ret); - env->mdb_data_path = kr_strcatdup(2, path, "/data.mdb"); + env->mdb_data_path = kr_absolutize_path(path, "data.mdb"); if (!env->mdb_data_path) { ret = ENOMEM; goto error_sys; diff --git a/lib/utils.c b/lib/utils.c index fcba71bb0..971794099 100644 --- a/lib/utils.c +++ b/lib/utils.c @@ -210,6 +210,31 @@ char* kr_strcatdup(unsigned n, ...) return result; } +char * kr_absolutize_path(const char *dirname, const char *fname) +{ + assert(dirname && fname); + char *result; + int aret; + if (dirname[0] == '/') { // absolute path is easier + aret = asprintf(&result, "%s/%s", dirname, fname); + } else { // relative path, but don't resolve symlinks + char buf[PATH_MAX]; + const char *cwd = getcwd(buf, sizeof(buf)); + if (!cwd) + return NULL; // errno has been set already + if (strcmp(dirname, ".") == 0) { + // get rid of one common case of extraneous "./" + aret = asprintf(&result, "%s/%s", cwd, fname); + } else { + aret = asprintf(&result, "%s/%s/%s", cwd, dirname, fname); + } + } + if (aret > 0) + return result; + errno = -aret; + return NULL; +} + int kr_memreserve(void *baton, void **mem, size_t elm_size, size_t want, size_t *have) { if (*have >= want) { diff --git a/lib/utils.h b/lib/utils.h index 48748d2bb..3b0179512 100644 --- a/lib/utils.h +++ b/lib/utils.h @@ -223,6 +223,11 @@ typedef array_t(ranked_rr_array_entry_t *) ranked_rr_array_t; KR_EXPORT char* kr_strcatdup(unsigned n, ...); +/** Construct absolute file path, without resolving symlinks. + * \return malloc-ed string or NULL (+errno in that case) */ +KR_EXPORT +char * kr_absolutize_path(const char *dirname, const char *fname); + /** You probably want kr_rand_* convenience functions instead. * This is a buffered version of gnutls_rnd(GNUTLS_RND_NONCE, ..) */ KR_EXPORT