commit cabcb752d7ecc2d16e6cb630b3de0684b4f97ec5
Author: Nick Mathewson <nickm(a)torproject.org>
Date: Mon Nov 20 10:10:13 2017 -0500
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.
---
src/common/storagedir.c | 25 +++++++++++++++++++++----
1 file changed, 21 insertions(+), 4 deletions(-)
diff --git a/src/common/storagedir.c b/src/common/storagedir.c
index 31933f64c..c471ea911 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;
}