]> git.ipfire.org Git - thirdparty/knot-resolver.git/commitdiff
lib/cache: avoid printing relative paths to cache
authorVladimír Čunát <vladimir.cunat@nic.cz>
Fri, 4 Sep 2020 17:24:21 +0000 (19:24 +0200)
committerPetr Špaček <petr.spacek@nic.cz>
Mon, 7 Sep 2020 15:47:46 +0000 (17:47 +0200)
lib/cache/api.c
lib/cache/cdb_lmdb.c
lib/utils.c
lib/utils.h

index 3e8351fad403d3399bf3d6d76c39c7c50017b141..d7794eca988d3802cf02771dec1c80a8052eb095 100644 (file)
@@ -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 */
index 3b986df82166ef79dc35f5a199efa4c2228df376..b56d8335e904666a3c60a4eb49a085882ed4a749 100644 (file)
@@ -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;
index fcba71bb0cb19f0a6d1f03e67ce704dbfbea18f7..97179409931658bbf93bf198884387c1d6e1c7db 100644 (file)
@@ -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) {
index 48748d2bb5a61ffa3b32409f19a7c53b491c4ad9..3b017951294208a5c87719d68031cea5decb89ce 100644 (file)
@@ -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