[tor-commits] [tor/master] Make file-reading and key-reading preserve errno

nickm at torproject.org nickm at torproject.org
Wed Jul 15 15:12:38 UTC 2015


commit b566cb9e84b095289a1c662e953218c9a7d1f77d
Author: Nick Mathewson <nickm at torproject.org>
Date:   Tue Jul 14 10:18:52 2015 -0400

    Make file-reading and key-reading preserve errno
    
    This is an important part of #16582.
---
 src/common/crypto_curve25519.c |   21 ++++++++++++++++-----
 src/common/util.c              |    5 +++++
 2 files changed, 21 insertions(+), 5 deletions(-)

diff --git a/src/common/crypto_curve25519.c b/src/common/crypto_curve25519.c
index 80b0d88..113ac89 100644
--- a/src/common/crypto_curve25519.c
+++ b/src/common/crypto_curve25519.c
@@ -201,7 +201,7 @@ crypto_write_tagged_contents_to_file(const char *fname,
  * <b>data_out_len</b>-byte buffer in <b>data_out</b>. Check that the
  * typestring matches <b>typestring</b>; store the tag into a newly allocated
  * string in <b>tag_out</b>. Return -1 on failure, and the number of bytes of
- * data on success. */
+ * data on success.  Preserves the errno from reading the file. */
 ssize_t
 crypto_read_tagged_contents_from_file(const char *fname,
                                       const char *typestring,
@@ -214,27 +214,36 @@ crypto_read_tagged_contents_from_file(const char *fname,
   struct stat st;
   ssize_t r = -1;
   size_t st_size = 0;
+  int saved_errno = 0;
 
   *tag_out = NULL;
   st.st_size = 0;
   content = read_file_to_str(fname, RFTS_BIN|RFTS_IGNORE_MISSING, &st);
-  if (! content)
+  if (! content) {
+    saved_errno = errno;
     goto end;
-  if (st.st_size < 32 || st.st_size > 32 + data_out_len)
+  }
+  if (st.st_size < 32 || st.st_size > 32 + data_out_len) {
+    saved_errno = EINVAL;
     goto end;
+  }
   st_size = (size_t)st.st_size;
 
   memcpy(prefix, content, 32);
   prefix[32] = 0;
   /* Check type, extract tag. */
   if (strcmpstart(prefix, "== ") || strcmpend(prefix, " ==") ||
-      ! tor_mem_is_zero(prefix+strlen(prefix), 32-strlen(prefix)))
+      ! tor_mem_is_zero(prefix+strlen(prefix), 32-strlen(prefix))) {
+    saved_errno = EINVAL;
     goto end;
+  }
 
   if (strcmpstart(prefix+3, typestring) ||
       3+strlen(typestring) >= 32 ||
-      strcmpstart(prefix+3+strlen(typestring), ": "))
+      strcmpstart(prefix+3+strlen(typestring), ": ")) {
+    saved_errno = EINVAL;
     goto end;
+  }
 
   *tag_out = tor_strndup(prefix+5+strlen(typestring),
                          strlen(prefix)-8-strlen(typestring));
@@ -246,6 +255,8 @@ crypto_read_tagged_contents_from_file(const char *fname,
   if (content)
     memwipe(content, 0, st_size);
   tor_free(content);
+  if (saved_errno)
+    errno = saved_errno;
   return r;
 }
 
diff --git a/src/common/util.c b/src/common/util.c
index 4490150..a140057 100644
--- a/src/common/util.c
+++ b/src/common/util.c
@@ -2571,7 +2571,9 @@ read_file_to_str_until_eof(int fd, size_t max_bytes_to_read, size_t *sz_out)
     string = tor_realloc(string, string_max);
     r = read(fd, string + pos, string_max - pos - 1);
     if (r < 0) {
+      int save_errno = errno;
       tor_free(string);
+      errno = save_errno;
       return NULL;
     }
 
@@ -2639,11 +2641,14 @@ read_file_to_str(const char *filename, int flags, struct stat *stat_out)
   if (S_ISFIFO(statbuf.st_mode)) {
     size_t sz = 0;
     string = read_file_to_str_until_eof(fd, FIFO_READ_MAX, &sz);
+    int save_errno = errno;
     if (string && stat_out) {
       statbuf.st_size = sz;
       memcpy(stat_out, &statbuf, sizeof(struct stat));
     }
     close(fd);
+    if (!string)
+      errno = save_errno;
     return string;
   }
 #endif





More information about the tor-commits mailing list