diff options
author | Nick Mathewson <nickm@torproject.org> | 2015-07-14 10:18:52 -0400 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2015-07-14 10:18:52 -0400 |
commit | b566cb9e84b095289a1c662e953218c9a7d1f77d (patch) | |
tree | 468a88d00dde062816f05df3afc7794c90d96a68 | |
parent | b06759edfda17205b8a027b2a369abefcaaba4fc (diff) | |
download | tor-b566cb9e84b095289a1c662e953218c9a7d1f77d.tar.gz tor-b566cb9e84b095289a1c662e953218c9a7d1f77d.zip |
Make file-reading and key-reading preserve errno
This is an important part of #16582.
-rw-r--r-- | src/common/crypto_curve25519.c | 21 | ||||
-rw-r--r-- | 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 80b0d88952..113ac89df7 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 449015054f..a140057dea 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 |