Explorar o código

Make file-reading and key-reading preserve errno

This is an important part of #16582.
Nick Mathewson %!s(int64=10) %!d(string=hai) anos
pai
achega
b566cb9e84
Modificáronse 2 ficheiros con 21 adicións e 5 borrados
  1. 16 5
      src/common/crypto_curve25519.c
  2. 5 0
      src/common/util.c

+ 16 - 5
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;
 }
 

+ 5 - 0
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