summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2017-11-20 10:10:13 -0500
committerNick Mathewson <nickm@torproject.org>2017-11-20 10:10:13 -0500
commitcabcb752d7ecc2d16e6cb630b3de0684b4f97ec5 (patch)
tree9ff1e47381d7bbb15e205b3ba99036dbdc8cca92
parent73585595245ac9551a1982575941e954bb870ad0 (diff)
downloadtor-cabcb752d7ecc2d16e6cb630b3de0684b4f97ec5.tar.gz
tor-cabcb752d7ecc2d16e6cb630b3de0684b4f97ec5.zip
In storagedir, take more care with errno on empty or mislabeled file
Required for 24099 fix -- we won't be able to act based on errno unless we can trust it.
-rw-r--r--src/common/storagedir.c25
1 files changed, 21 insertions, 4 deletions
diff --git a/src/common/storagedir.c b/src/common/storagedir.c
index 31933f64c2..c471ea911f 100644
--- a/src/common/storagedir.c
+++ b/src/common/storagedir.c
@@ -187,14 +187,19 @@ storage_dir_get_usage(storage_dir_t *d)
return d->usage;
}
-/** Mmap a specified file within <b>d</b>. */
+/** Mmap a specified file within <b>d</b>.
+ *
+ * On failure, return NULL and set errno as for tor_mmap_file(). */
tor_mmap_t *
storage_dir_map(storage_dir_t *d, const char *fname)
{
char *path = NULL;
tor_asprintf(&path, "%s/%s", d->directory, fname);
tor_mmap_t *result = tor_mmap_file(path);
+ int errval = errno;
tor_free(path);
+ if (result == NULL)
+ errno = errval;
return result;
}
@@ -364,6 +369,10 @@ storage_dir_save_labeled_to_file(storage_dir_t *d,
* the data's size into *<b>sz_out</b>. On success, also return a tor_mmap_t
* object whose contents should not be used -- it needs to be kept around,
* though, for as long as <b>data_out</b> is going to be valid.
+ *
+ * On failure, set errno as for tor_mmap_file() if the file was missing or
+ * empty, and set errno to EINVAL if the file was not in the labeled
+ * format expected.
*/
tor_mmap_t *
storage_dir_map_labeled(storage_dir_t *dir,
@@ -373,13 +382,20 @@ storage_dir_map_labeled(storage_dir_t *dir,
size_t *sz_out)
{
tor_mmap_t *m = storage_dir_map(dir, fname);
- if (! m)
+ int errval;
+ if (! m) {
+ errval = errno;
goto err;
+ }
const char *nulp = memchr(m->data, '\0', m->size);
- if (! nulp)
+ if (! nulp) {
+ errval = EINVAL;
goto err;
- if (labels_out && config_get_lines(m->data, labels_out, 0) < 0)
+ }
+ if (labels_out && config_get_lines(m->data, labels_out, 0) < 0) {
+ errval = EINVAL;
goto err;
+ }
size_t offset = nulp - m->data + 1;
tor_assert(offset <= m->size);
*data_out = (const uint8_t *)(m->data + offset);
@@ -388,6 +404,7 @@ storage_dir_map_labeled(storage_dir_t *dir,
return m;
err:
tor_munmap_file(m);
+ errno = errval;
return NULL;
}