The *get* state query functions for the SRVs now only return const pointers
and the DEL action needs to be used to delete the SRVs from the state.
Signed-off-by: David Goulet <dgoulet@torproject.org>
This patch makes us retain the intermediate list of K=V entries for
the duration of computing our vote, and lets us use that list with
a new function in order to look up parameters before the consensus
is published.
We can't actually use this function yet because of #19011: our
existing code to do this doesn't actually work, and we'll need a new
consensus method to start using it.
Closes ticket #19012.
Commit and reveal length macro changed from int to unsigned long int
(size_t) because of the sizeof().
Signed-off-by: David Goulet <dgoulet@torproject.org>
See ticket #19132 for the clang/llvm warning.
Since voting_schedule is a global static struct, it will be initialized
to zero even without explicitly initializing it with {0}.
This is what the C spec says:
If an object that has automatic storage duration is not initialized
explicitly, its value is indeterminate. If an object that has static
storage duration is not initialized explicitly, then:
— if it has pointer type, it is initialized to a null pointer;
— if it has arithmetic type, it is initialized to (positive or unsigned) zero;
— if it is an aggregate, every member is initialized (recursively) according to these rules;
— if it is a union, the first named member is initialized (recursively) according to these rules.
Code has been changed so every RSA fingerprint for a commit in our state is
validated before being used. This fixes the unit tests by mocking one of the
key function and updating the hardcoded state string.
Also, fix a time parsing overflow on platforms with 32bit time_t
Signed-off-by: David Goulet <dgoulet@torproject.org>
Signed-off-by: George Kadianakis <desnacked@riseup.net>
We assert on it using the ASSERT_COMMIT_VALID() macro in critical places
where we use them expecting a commit to be valid.
Signed-off-by: David Goulet <dgoulet@torproject.org>
The prop250 code used the RSA identity key fingerprint to index commit in a
digestmap instead of using the digest.
To behavior change except the fact that we are actually using digestmap
correctly.
Signed-off-by: David Goulet <dgoulet@torproject.org>
This commit makes it that tor now uses the shared random protocol by
initializing the subsystem.
Signed-off-by: David Goulet <dgoulet@torproject.org>
Signed-off-by: George Kadianakis <desnacked@riseup.net>
One of the last piece that parses the votes and consensus in order to update
our state and make decision for the SR values.
We need to inform the SR subsystem when we set the current consensus because
this can be called when loaded from file or downloaded from other authorities
or computed.
The voting schedule is used for the SR timings since we are bound to the
voting system.
Signed-off-by: David Goulet <dgoulet@torproject.org>
Signed-off-by: George Kadianakis <desnacked@riseup.net>
This commit adds the commit(s) line in the vote as well as the SR values. It
also has the mechanism to add the majority SRVs in the consensus.
Signed-off-by: George Kadianakis <desnacked@riseup.net>
Signed-off-by: David Goulet <dgoulet@torproject.org>
This adds the logic of commit and SR values generation. Furthermore, the
concept of a protocol run is added that is commit is generated at the right
time as well as SR values which are also rotated before a new protocol run.
Signed-off-by: George Kadianakis <desnacked@riseup.net>
Signed-off-by: David Goulet <dgoulet@torproject.org>
From 0.2.7.2-alpha onwards, Exits would reject all the IP addresses
they knew about in their exit policy. But this may have disclosed
addresses that were otherwise unlisted.
Now, only advertised addresses are rejected by default by
ExitPolicyRejectPrivate. All known addresses are only rejected when
ExitPolicyRejectLocalInterfaces is explicitly set to 1.
Validate that tv_usec inputs to tv_udiff and tv_mdiff are in range.
Do internal calculations in tv_udiff and tv_mdiff in 64-bit,
which makes the function less prone to integer overflow,
particularly on platforms where long and time_t are 32-bit,
but tv_sec is 64-bit, like some BSD configurations.
Check every addition and subtraction that could overflow.
If we manually remove fallbacks in C by adding '/*' and '*/' on separate
lines, stem still parses them as being present, because it only looks at
the start of a line.
Add a comment to this effect in the generated source code.
Remove a fallback that changed its fingerprint after it was listed
This happened after to a software update:
https://lists.torproject.org/pipermail/tor-relays/2016-June/009473.html
Remove a fallback that changed IPv4 address
Remove two fallbacks that were slow to deliver consensuses,
we can't guarantee they'll be fast in future.
Blacklist all these fallbacks until operators confirm they're stable.
This commit introduces two new files with their header.
"shared_random.c" contains basic functions to initialize the state and allow
commit decoding for the disk state to be able to parse them from disk.
"shared_random_state.c" contains everything that has to do with the state
for both our memory and disk. Lots of helper functions as well as a
mechanism to query the state in a synchronized way.
Signed-off-by: David Goulet <dgoulet@torproject.org>
Signed-off-by: George Kadianakis <desnacked@riseup.net>
Make sure to memset(0) the destination buffer so we don't leave any
uninitialized data.
Fixes#19462
Signed-off-by: David Goulet <dgoulet@torproject.org>
This hack provides a way to make sure we can see coverage from
test-switch-id. If you set OVERRIDE_GCDA_PERMISSIONS_HACK, we
temporarily make the .gcda files mode 0666 before we run the
test scripts, and then we set them to 0644 again afterwards.
That's necessary because the test_switch_id.sh script does a
setuid() to 'nobody' part way through, and drops the ability to
change its mind back.
Slow system can sometime take more than 10 seconds to reach the test
callsite resulting in the unit test failing when using time in the future or
in the past.
Fixes#19465
Signed-off-by: David Goulet <dgoulet@torproject.org>
base16_decodes() now returns the number of decoded bytes. It's interface
changes from returning a "int" to a "ssize_t". Every callsite now checks the
returned value.
Fixes#14013
Signed-off-by: David Goulet <dgoulet@torproject.org>
realloc()ing a thing in order to try to save memory on it just
doesn't make sense with today's allocators. Instead, let's use the
fact that whenever we decompress something, either it isn't too big,
or we chop it up, or we reallocate it.
zlib 1.2 came out in 2003; earlier versions should be dead by now.
Our workaround code was only preventing us from using the gzip
encoding (if we decide to do so), and having some dead code linger
around in torgzip.c
The Autoconf macro AC_USE_SYSTEM_EXTENSIONS defines preprocessor macros
which turn on extensions to C and POSIX. The macro also makes it easier
for developers to use the extensions without needing (or forgetting) to
define them manually.
The macro can be safely used because it was introduced in Autoconf 2.60
and Tor requires Autoconf 2.63 and above.
When deleting an ephemeral HS, we were only iterating on circuit with an
OPEN state. However, it could be possible that an intro point circuit didn't
reached the open state yet.
This commit makes it that we close the circuit regardless of its state
except if it was already marked for close.
Fixes#18604
Signed-off-by: David Goulet <dgoulet@torproject.org>
The FetchHidServDescriptors check was placed before the descriptor cache
lookup which made the option not working because it was never using the
cache in the first place.
Fixes#18704
Patched-by: twim
Signef-off-by: David Goulet <dgoulet@torproject.org>
There's accessors to get at things, but it ends up being rather
cumbersome. The only place where behavior should change is that the
code will fail instead of attempting to generate a new DH key if our
internal sanity check fails.
Like the previous commit, this probably breaks snapshots prior to pre5.
Instead of `ERR_remove_thread_state()` having a modified prototype, it
now has the old prototype and a deprecation annotation. Since it's
pointless to add extra complexity just to remain compatible with an old
OpenSSL development snapshot, update the code to work with 1.1.0pre5
and later.
When you divide an int by an int and get a fraction and _then_ cast
to double, coverity assumes that you meant to cast to a double
first.
In my fix for -Wfloat-conversion in 493499a339, I
did something like this that coverity didn't like.
Instead, I'm taking another approach here.
Fixes CID 1232089, I hope.
This is a big-ish patch, but it's very straightforward. Under this
clang warning, we're not actually allowed to have a global variable
without a previous extern declaration for it. The cases where we
violated this rule fall into three roughly equal groups:
* Stuff that should have been static.
* Stuff that was global but where the extern was local to some
other C file.
* Stuff that was only global when built for the unit tests, that
needed a conditional extern in the headers.
The first two were IMO genuine problems; the last is a wart of how
we build tests.
This warning triggers on silently promoting a float to a double. In
our code, it's just a sign that somebody used a float by mistake,
since we always prefer double.
This warning, IIUC, means that the compiler doesn't like it when it
sees a NULL check _after_ we've already dereferenced the
variable. In such cases, it considers itself free to eliminate the
NULL check.
There are a couple of tricky cases:
One was the case related to the fact that tor_addr_to_in6() can
return NULL if it gets a non-AF_INET6 address. The fix was to
create a variant which asserts on the address type, and never
returns NULL.
This is a fairly easy way for us to get our test coverage up on
compat_threads.c and workqueue.c -- I already implemented these
tests, so we might as well enable them.
Previously, we used !directory_fetches_from_authorities() to predict
that we would tunnel connections. But the rules have changed
somewhat over the course of 0.2.8
So, back long ago, XXX012 meant, "before Tor 0.1.2 is released, we
had better revisit this comment and fix it!"
But we have a huge pile of such comments accumulated for a large
number of released versions! Not cool.
So, here's what I tried to do:
* 0.2.9 and 0.2.8 are retained, since those are not yet released.
* XXX+ or XXX++ or XXX++++ or whatever means, "This one looks
quite important!"
* The others, after one-by-one examination, are downgraded to
plain old XXX. Which doesn't mean they aren't a problem -- just
that they cannot possibly be a release-blocking problem.
There was a > that should have been an ==, and a missing !. These
together prevented us from issuing a warning in the case that a
nickname matched an Unnamed node only.
Fixes bug 19203; bugfix on 0.2.3.1-alpha.
There are a few places where we want to disable a warning: for
example, when it's impossible to call a legacy API without
triggering it, or when it's impossible to include an external header
without triggering it.
This pile of macros uses GCC's c99 _Pragma support, plus the usual
macro trickery, to enable and disable warnings.
Remove support for "GET /tor/bytes.txt" DirPort request, and
"GETINFO dir-usage" controller request, which were only available
via a compile-time option in Tor anyway.
Feature was added in 0.2.2.1-alpha. Resolves ticket 19035.
I introduced this bug when I moved signing_key_cert into
signed_descriptor_t. Bug not in any released Tor. Fixes bug 19175, and
another case of 19128.
Just like signed_descriptor_from_routerinfo(), routerlist_reparse_old()
copies the fields from one signed_descriptor_t to another, and then
clears the fields from the original that would have been double-freed by
freeing the original. But when I fixed the s_d_f_r() bug [#19128] in
50cbf22099, I missed the fact that the code was duplicated in
r_p_o().
Duplicated code strikes again!
For a longer-term solution here, I am not only adding the missing fix to
r_p_o(): I am also extracting the duplicated code into a new function.
Many thanks to toralf for patiently sending me stack traces until
one made sense.
If OpenSSL fails to generate an RSA key, do not retain a dangling
pointer to the previous (uninitialized) key value. The impact here
should be limited to a difficult-to-trigger crash, if OpenSSL is
running an engine that makes key generation failures possible, or if
OpenSSL runs out of memory. Fixes bug 19152; bugfix on
0.2.1.10-alpha. Found by Yuan Jochen Kang, Suman Jana, and Baishakhi
Ray.
This is potentially scary stuff, so let me walk through my analysis.
I think this is a bug, and a backport candidate, but not remotely
triggerable in any useful way.
Observation 1a:
Looking over the OpenSSL code here, the only way we can really fail in
the non-engine case is if malloc() fails. But if malloc() is failing,
then tor_malloc() calls should be tor_asserting -- the only way that an
attacker could do an exploit here would be to figure out some way to
make malloc() fail when openssl does it, but work whenever Tor does it.
(Also ordinary malloc() doesn't fail on platforms like Linux that
overcommit.)
Observation 1b:
Although engines are _allowed_ to fail in extra ways, I can't find much
evidence online that they actually _do_ fail in practice. More evidence
would be nice, though.
Observation 2:
We don't call crypto_pk_generate*() all that often, and we don't do it
in response to external inputs. The only way to get it to happen
remotely would be by causing a hidden service to build new introduction
points.
Observation 3a:
So, let's assume that both of the above observations are wrong, and the
attacker can make us generate a crypto_pk_env_t with a dangling pointer
in its 'key' field, and not immediately crash.
This dangling pointer will point to what used to be an RSA structure,
with the fields all set to NULL. Actually using this RSA structure,
before the memory is reused for anything else, will cause a crash.
In nearly every function where we call crypto_pk_generate*(), we quickly
use the RSA key pointer -- either to sign something, or to encode the
key, or to free the key. The only exception is when we generate an
intro key in rend_consider_services_intro_points(). In that case, we
don't actually use the key until the intro circuit is opened -- at which
point we encode it, and use it to sign an introduction request.
So in order to exploit this bug to do anything besides crash Tor, the
attacker needs to make sure that by the time the introduction circuit
completes, either:
* the e, d, and n BNs look valid, and at least one of the other BNs is
still NULL.
OR
* all 8 of the BNs must look valid.
To look like a valid BN, *they* all need to have their 'top' index plus
their 'd' pointer indicate an addressable region in memory.
So actually getting useful data of of this, rather than a crash, is
going to be pretty damn hard. You'd have to force an introduction point
to be created (or wait for one to be created), and force that particular
crypto_pk_generate*() to fail, and then arrange for the memory that the
RSA points to to in turn point to 3...8 valid BNs, all by the time the
introduction circuit completes.
Naturally, the signature won't check as valid [*], so the intro point
will reject the ESTABLISH_INTRO cell. So you need to _be_ the
introduction point, or you don't actually see this information.
[*] Okay, so if you could somehow make the 'rsa' pointer point to a
different valid RSA key, then you'd get a valid signature of an
ESTABLISH_INTRO cell using a key that was supposed to be used for
something else ... but nothing else looks like that, so you can't use
that signature elsewhere.
Observation 3b:
Your best bet as an attacker would be to make the dangling RSA pointer
actually contain a fake method, with a fake RSA_private_encrypt
function that actually pointed to code you wanted to execute. You'd
still need to transit 3 or 4 pointers deep though in order to make that
work.
Conclusion:
By 1, you probably can't trigger this without Tor crashing from OOM.
By 2, you probably can't trigger this reliably.
By 3, even if I'm wrong about 1 and 2, you have to jump through a pretty
big array of hoops in order to get any kind of data leak or code
execution.
So I'm calling it a bug, but not a security hole. Still worth
patching.
Fortunately, the arithmetic cannot actually overflow, so long as we
*always* check for the size of potentially hostile input before
copying it. I think we do, though. We do check each line against
MAX_LINE_LENGTH, and each object name or object against
MAX_UNPARSED_OBJECT_SIZE, both of which are 128k. So to get this
overflow, we need to have our memarea allocated way way too high up
in RAM, which most allocators won't actually do.
Bugfix on 0.2.1.1-alpha, where memarea was introduced.
Found by Guido Vranken.
Previously, if the header was present, we'd proceed even if the
function wasn't there.
Easy fix for bug 19161. A better fix would involve trying harder to
find libscrypt_scrypt.