How does the most recently found critical vulnerability (CVE-2018-17144) work?
Clash Royale CLAN TAG#URR8PPP
up vote
14
down vote
favorite
If you were a miner, what are the steps you would take to create the extra (21,000,012.5th) bitcoin?
Where in the source code is this exactly (link)?
Why can't this be done by a non-miner?
Also, which forks are/were vulnerable?
reward-schedule error weaknesses source-code
add a comment |Â
up vote
14
down vote
favorite
If you were a miner, what are the steps you would take to create the extra (21,000,012.5th) bitcoin?
Where in the source code is this exactly (link)?
Why can't this be done by a non-miner?
Also, which forks are/were vulnerable?
reward-schedule error weaknesses source-code
add a comment |Â
up vote
14
down vote
favorite
up vote
14
down vote
favorite
If you were a miner, what are the steps you would take to create the extra (21,000,012.5th) bitcoin?
Where in the source code is this exactly (link)?
Why can't this be done by a non-miner?
Also, which forks are/were vulnerable?
reward-schedule error weaknesses source-code
If you were a miner, what are the steps you would take to create the extra (21,000,012.5th) bitcoin?
Where in the source code is this exactly (link)?
Why can't this be done by a non-miner?
Also, which forks are/were vulnerable?
reward-schedule error weaknesses source-code
reward-schedule error weaknesses source-code
asked Sep 22 at 0:03
hedgedandlevered
7441518
7441518
add a comment |Â
add a comment |Â
1 Answer
1
active
oldest
votes
up vote
23
down vote
accepted
If you were a miner, what are the steps you would take to create the extra (21,000,012.5th) bitcoin?
Where in the source code is this exactly (link)?
There are two components to CVE-2018-17144. There is a crash bug and an inflation bug. Both are triggered by almost the same scenario: a transaction contains an input multiple times.
In general, how this would work is as follows: lets suppose a miner has an unspent output A for 1 BTC. They create a transaction with that input in twice, so input 1 spends from output A and input 2 also spends from output A. The output of that transaction has a value of 2 BTC. Note how the output's value is larger than the value of output A, but if you had output A twice, the value is correct.
The miner would then take this transaction and include it in a block that he is mining. Once the miner find a block with his transaction included in it, he broadcasts it to the Bitcoin network.
When a Bitcoin Core 0.14.x node receives this block, it will validate the block, but it will skip the duplicate input check because of the false
parameter on this line. So the transaction the miner made will pass this step of validation, and the other transaction validation steps, including input script validation, until it reaches this loop. In this loop, the inputs to the transaction are being marked as spent in the UTXO database. The first time the duplicated input is seen, it is marked as spent. But the second time it is seen, the coin is already marked as spent so coins->vout[nPos].IsNull()
will be true. This means that it will go into this if statement and subsequently hit the assert
statement that follows. The assert causes the software to crash.
For Bitcoin Core 0.15.0 - 0.16.2, the behavior is different. This is due to the change in how the UTXO database is structured. Everything is largely the same until the same loop is reached. Here, instead of returning whether the output was spent, SpendCoin
actually returns whether the input exists in the database. So the first time, it will pass as expected, but the second time, instead of returning false
, it still returns true
.
Looking at SpendCoin
, you can see that it only returns false when it is unable to fetch the coin (object representing a UTXO) from the database. With the new database structure, this makes sense as the output should be removed from the database when it is spent. But, if you look a few lines down, you see that it only deletes the coin when it is marked as FRESH
. In the case the coin was FRESH
, SpendCoin
would delete the object on the first pass so the second pass the coin would not be found and thus it would return false. This triggers the assert
following the function call causing the node to shutdown.
If the coin was not FRESH
, the coin object itself is not deleted, but its contents are cleared. This means that the second time the input is seen, if the coin was not FRESH
, SpendCoin
would still return true as the object still exists in memory, which means that it passes the assert that follows the SpendCoin
(which caused the crash when the coin was not FRESH
). Then validation continues as normal, and the output this transaction created is added to the UTXO database, which means that money that shouldn't exist now exists in the UTXO database.
So now the question is, when are UTXOs marked as FRESH
? They are marked FRESH
when they are added to the UTXO database. But the UTXO database is still only in memory (as a cache). When it is saved to disk, the entries in memory are then no longer marked as FRESH
. This saving to disk happens after every block (as well as at other times, but that is not important).
Thus, if a miner has an output that was part of a transaction that has already confirmed, and he spends the output twice in the same transaction (so the transaction has two inputs that refer to the same output), and this transaction is not broadcast to the network but instead included in a block that he mines, he is able to create a new output that has twice the value of the output that he spent, thereby creating coins.
Why can't this be done by a non-miner?
The reason that this cannot be done by a non-miner is because transactions that are received outside of blocks are still checked for duplicate inputs. The transaction will be rejected as invalid and not added to the node's mempool, so the transaction will never get into a block. It is only transactions with duplicate inputs that get into blocks that trigger this vulnerability, and thus only miners can do this as they must knowingly insert an invalid transaction into their block.
Also, which forks are/were vulnerable?
Any fork whose software includes commit eecffe50efc3944d713c701fa375dacbf17fb7cf
. This would mean any software forked from or pulled in changes from Bitcoin Core after November 10th, 2016.
Would a node that receives the block as a compact block check for the duplicate?
â Murchâ¦
Sep 22 at 18:16
2
No, it would not. The transaction with the duplicate input would not be in the mempool so it would be sent along with the block (as part of ablocktxn
message). Such transactions are not run through the mempool acceptance code. Instead the block is reconstructed and run through the normal block acceptance code.
â Andrew Chowâ¦
Sep 22 at 19:04
Great write-up, thank you! It seems to me having a bool flag such asfCheckDuplicateInputs
seems pretty unfortunate. It is quite easy to set it to an invalid value. I'm just wondering if we shouldn't be more explicit and verbose in those critical parts
â tsusanka
Sep 26 at 7:54
add a comment |Â
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
23
down vote
accepted
If you were a miner, what are the steps you would take to create the extra (21,000,012.5th) bitcoin?
Where in the source code is this exactly (link)?
There are two components to CVE-2018-17144. There is a crash bug and an inflation bug. Both are triggered by almost the same scenario: a transaction contains an input multiple times.
In general, how this would work is as follows: lets suppose a miner has an unspent output A for 1 BTC. They create a transaction with that input in twice, so input 1 spends from output A and input 2 also spends from output A. The output of that transaction has a value of 2 BTC. Note how the output's value is larger than the value of output A, but if you had output A twice, the value is correct.
The miner would then take this transaction and include it in a block that he is mining. Once the miner find a block with his transaction included in it, he broadcasts it to the Bitcoin network.
When a Bitcoin Core 0.14.x node receives this block, it will validate the block, but it will skip the duplicate input check because of the false
parameter on this line. So the transaction the miner made will pass this step of validation, and the other transaction validation steps, including input script validation, until it reaches this loop. In this loop, the inputs to the transaction are being marked as spent in the UTXO database. The first time the duplicated input is seen, it is marked as spent. But the second time it is seen, the coin is already marked as spent so coins->vout[nPos].IsNull()
will be true. This means that it will go into this if statement and subsequently hit the assert
statement that follows. The assert causes the software to crash.
For Bitcoin Core 0.15.0 - 0.16.2, the behavior is different. This is due to the change in how the UTXO database is structured. Everything is largely the same until the same loop is reached. Here, instead of returning whether the output was spent, SpendCoin
actually returns whether the input exists in the database. So the first time, it will pass as expected, but the second time, instead of returning false
, it still returns true
.
Looking at SpendCoin
, you can see that it only returns false when it is unable to fetch the coin (object representing a UTXO) from the database. With the new database structure, this makes sense as the output should be removed from the database when it is spent. But, if you look a few lines down, you see that it only deletes the coin when it is marked as FRESH
. In the case the coin was FRESH
, SpendCoin
would delete the object on the first pass so the second pass the coin would not be found and thus it would return false. This triggers the assert
following the function call causing the node to shutdown.
If the coin was not FRESH
, the coin object itself is not deleted, but its contents are cleared. This means that the second time the input is seen, if the coin was not FRESH
, SpendCoin
would still return true as the object still exists in memory, which means that it passes the assert that follows the SpendCoin
(which caused the crash when the coin was not FRESH
). Then validation continues as normal, and the output this transaction created is added to the UTXO database, which means that money that shouldn't exist now exists in the UTXO database.
So now the question is, when are UTXOs marked as FRESH
? They are marked FRESH
when they are added to the UTXO database. But the UTXO database is still only in memory (as a cache). When it is saved to disk, the entries in memory are then no longer marked as FRESH
. This saving to disk happens after every block (as well as at other times, but that is not important).
Thus, if a miner has an output that was part of a transaction that has already confirmed, and he spends the output twice in the same transaction (so the transaction has two inputs that refer to the same output), and this transaction is not broadcast to the network but instead included in a block that he mines, he is able to create a new output that has twice the value of the output that he spent, thereby creating coins.
Why can't this be done by a non-miner?
The reason that this cannot be done by a non-miner is because transactions that are received outside of blocks are still checked for duplicate inputs. The transaction will be rejected as invalid and not added to the node's mempool, so the transaction will never get into a block. It is only transactions with duplicate inputs that get into blocks that trigger this vulnerability, and thus only miners can do this as they must knowingly insert an invalid transaction into their block.
Also, which forks are/were vulnerable?
Any fork whose software includes commit eecffe50efc3944d713c701fa375dacbf17fb7cf
. This would mean any software forked from or pulled in changes from Bitcoin Core after November 10th, 2016.
Would a node that receives the block as a compact block check for the duplicate?
â Murchâ¦
Sep 22 at 18:16
2
No, it would not. The transaction with the duplicate input would not be in the mempool so it would be sent along with the block (as part of ablocktxn
message). Such transactions are not run through the mempool acceptance code. Instead the block is reconstructed and run through the normal block acceptance code.
â Andrew Chowâ¦
Sep 22 at 19:04
Great write-up, thank you! It seems to me having a bool flag such asfCheckDuplicateInputs
seems pretty unfortunate. It is quite easy to set it to an invalid value. I'm just wondering if we shouldn't be more explicit and verbose in those critical parts
â tsusanka
Sep 26 at 7:54
add a comment |Â
up vote
23
down vote
accepted
If you were a miner, what are the steps you would take to create the extra (21,000,012.5th) bitcoin?
Where in the source code is this exactly (link)?
There are two components to CVE-2018-17144. There is a crash bug and an inflation bug. Both are triggered by almost the same scenario: a transaction contains an input multiple times.
In general, how this would work is as follows: lets suppose a miner has an unspent output A for 1 BTC. They create a transaction with that input in twice, so input 1 spends from output A and input 2 also spends from output A. The output of that transaction has a value of 2 BTC. Note how the output's value is larger than the value of output A, but if you had output A twice, the value is correct.
The miner would then take this transaction and include it in a block that he is mining. Once the miner find a block with his transaction included in it, he broadcasts it to the Bitcoin network.
When a Bitcoin Core 0.14.x node receives this block, it will validate the block, but it will skip the duplicate input check because of the false
parameter on this line. So the transaction the miner made will pass this step of validation, and the other transaction validation steps, including input script validation, until it reaches this loop. In this loop, the inputs to the transaction are being marked as spent in the UTXO database. The first time the duplicated input is seen, it is marked as spent. But the second time it is seen, the coin is already marked as spent so coins->vout[nPos].IsNull()
will be true. This means that it will go into this if statement and subsequently hit the assert
statement that follows. The assert causes the software to crash.
For Bitcoin Core 0.15.0 - 0.16.2, the behavior is different. This is due to the change in how the UTXO database is structured. Everything is largely the same until the same loop is reached. Here, instead of returning whether the output was spent, SpendCoin
actually returns whether the input exists in the database. So the first time, it will pass as expected, but the second time, instead of returning false
, it still returns true
.
Looking at SpendCoin
, you can see that it only returns false when it is unable to fetch the coin (object representing a UTXO) from the database. With the new database structure, this makes sense as the output should be removed from the database when it is spent. But, if you look a few lines down, you see that it only deletes the coin when it is marked as FRESH
. In the case the coin was FRESH
, SpendCoin
would delete the object on the first pass so the second pass the coin would not be found and thus it would return false. This triggers the assert
following the function call causing the node to shutdown.
If the coin was not FRESH
, the coin object itself is not deleted, but its contents are cleared. This means that the second time the input is seen, if the coin was not FRESH
, SpendCoin
would still return true as the object still exists in memory, which means that it passes the assert that follows the SpendCoin
(which caused the crash when the coin was not FRESH
). Then validation continues as normal, and the output this transaction created is added to the UTXO database, which means that money that shouldn't exist now exists in the UTXO database.
So now the question is, when are UTXOs marked as FRESH
? They are marked FRESH
when they are added to the UTXO database. But the UTXO database is still only in memory (as a cache). When it is saved to disk, the entries in memory are then no longer marked as FRESH
. This saving to disk happens after every block (as well as at other times, but that is not important).
Thus, if a miner has an output that was part of a transaction that has already confirmed, and he spends the output twice in the same transaction (so the transaction has two inputs that refer to the same output), and this transaction is not broadcast to the network but instead included in a block that he mines, he is able to create a new output that has twice the value of the output that he spent, thereby creating coins.
Why can't this be done by a non-miner?
The reason that this cannot be done by a non-miner is because transactions that are received outside of blocks are still checked for duplicate inputs. The transaction will be rejected as invalid and not added to the node's mempool, so the transaction will never get into a block. It is only transactions with duplicate inputs that get into blocks that trigger this vulnerability, and thus only miners can do this as they must knowingly insert an invalid transaction into their block.
Also, which forks are/were vulnerable?
Any fork whose software includes commit eecffe50efc3944d713c701fa375dacbf17fb7cf
. This would mean any software forked from or pulled in changes from Bitcoin Core after November 10th, 2016.
Would a node that receives the block as a compact block check for the duplicate?
â Murchâ¦
Sep 22 at 18:16
2
No, it would not. The transaction with the duplicate input would not be in the mempool so it would be sent along with the block (as part of ablocktxn
message). Such transactions are not run through the mempool acceptance code. Instead the block is reconstructed and run through the normal block acceptance code.
â Andrew Chowâ¦
Sep 22 at 19:04
Great write-up, thank you! It seems to me having a bool flag such asfCheckDuplicateInputs
seems pretty unfortunate. It is quite easy to set it to an invalid value. I'm just wondering if we shouldn't be more explicit and verbose in those critical parts
â tsusanka
Sep 26 at 7:54
add a comment |Â
up vote
23
down vote
accepted
up vote
23
down vote
accepted
If you were a miner, what are the steps you would take to create the extra (21,000,012.5th) bitcoin?
Where in the source code is this exactly (link)?
There are two components to CVE-2018-17144. There is a crash bug and an inflation bug. Both are triggered by almost the same scenario: a transaction contains an input multiple times.
In general, how this would work is as follows: lets suppose a miner has an unspent output A for 1 BTC. They create a transaction with that input in twice, so input 1 spends from output A and input 2 also spends from output A. The output of that transaction has a value of 2 BTC. Note how the output's value is larger than the value of output A, but if you had output A twice, the value is correct.
The miner would then take this transaction and include it in a block that he is mining. Once the miner find a block with his transaction included in it, he broadcasts it to the Bitcoin network.
When a Bitcoin Core 0.14.x node receives this block, it will validate the block, but it will skip the duplicate input check because of the false
parameter on this line. So the transaction the miner made will pass this step of validation, and the other transaction validation steps, including input script validation, until it reaches this loop. In this loop, the inputs to the transaction are being marked as spent in the UTXO database. The first time the duplicated input is seen, it is marked as spent. But the second time it is seen, the coin is already marked as spent so coins->vout[nPos].IsNull()
will be true. This means that it will go into this if statement and subsequently hit the assert
statement that follows. The assert causes the software to crash.
For Bitcoin Core 0.15.0 - 0.16.2, the behavior is different. This is due to the change in how the UTXO database is structured. Everything is largely the same until the same loop is reached. Here, instead of returning whether the output was spent, SpendCoin
actually returns whether the input exists in the database. So the first time, it will pass as expected, but the second time, instead of returning false
, it still returns true
.
Looking at SpendCoin
, you can see that it only returns false when it is unable to fetch the coin (object representing a UTXO) from the database. With the new database structure, this makes sense as the output should be removed from the database when it is spent. But, if you look a few lines down, you see that it only deletes the coin when it is marked as FRESH
. In the case the coin was FRESH
, SpendCoin
would delete the object on the first pass so the second pass the coin would not be found and thus it would return false. This triggers the assert
following the function call causing the node to shutdown.
If the coin was not FRESH
, the coin object itself is not deleted, but its contents are cleared. This means that the second time the input is seen, if the coin was not FRESH
, SpendCoin
would still return true as the object still exists in memory, which means that it passes the assert that follows the SpendCoin
(which caused the crash when the coin was not FRESH
). Then validation continues as normal, and the output this transaction created is added to the UTXO database, which means that money that shouldn't exist now exists in the UTXO database.
So now the question is, when are UTXOs marked as FRESH
? They are marked FRESH
when they are added to the UTXO database. But the UTXO database is still only in memory (as a cache). When it is saved to disk, the entries in memory are then no longer marked as FRESH
. This saving to disk happens after every block (as well as at other times, but that is not important).
Thus, if a miner has an output that was part of a transaction that has already confirmed, and he spends the output twice in the same transaction (so the transaction has two inputs that refer to the same output), and this transaction is not broadcast to the network but instead included in a block that he mines, he is able to create a new output that has twice the value of the output that he spent, thereby creating coins.
Why can't this be done by a non-miner?
The reason that this cannot be done by a non-miner is because transactions that are received outside of blocks are still checked for duplicate inputs. The transaction will be rejected as invalid and not added to the node's mempool, so the transaction will never get into a block. It is only transactions with duplicate inputs that get into blocks that trigger this vulnerability, and thus only miners can do this as they must knowingly insert an invalid transaction into their block.
Also, which forks are/were vulnerable?
Any fork whose software includes commit eecffe50efc3944d713c701fa375dacbf17fb7cf
. This would mean any software forked from or pulled in changes from Bitcoin Core after November 10th, 2016.
If you were a miner, what are the steps you would take to create the extra (21,000,012.5th) bitcoin?
Where in the source code is this exactly (link)?
There are two components to CVE-2018-17144. There is a crash bug and an inflation bug. Both are triggered by almost the same scenario: a transaction contains an input multiple times.
In general, how this would work is as follows: lets suppose a miner has an unspent output A for 1 BTC. They create a transaction with that input in twice, so input 1 spends from output A and input 2 also spends from output A. The output of that transaction has a value of 2 BTC. Note how the output's value is larger than the value of output A, but if you had output A twice, the value is correct.
The miner would then take this transaction and include it in a block that he is mining. Once the miner find a block with his transaction included in it, he broadcasts it to the Bitcoin network.
When a Bitcoin Core 0.14.x node receives this block, it will validate the block, but it will skip the duplicate input check because of the false
parameter on this line. So the transaction the miner made will pass this step of validation, and the other transaction validation steps, including input script validation, until it reaches this loop. In this loop, the inputs to the transaction are being marked as spent in the UTXO database. The first time the duplicated input is seen, it is marked as spent. But the second time it is seen, the coin is already marked as spent so coins->vout[nPos].IsNull()
will be true. This means that it will go into this if statement and subsequently hit the assert
statement that follows. The assert causes the software to crash.
For Bitcoin Core 0.15.0 - 0.16.2, the behavior is different. This is due to the change in how the UTXO database is structured. Everything is largely the same until the same loop is reached. Here, instead of returning whether the output was spent, SpendCoin
actually returns whether the input exists in the database. So the first time, it will pass as expected, but the second time, instead of returning false
, it still returns true
.
Looking at SpendCoin
, you can see that it only returns false when it is unable to fetch the coin (object representing a UTXO) from the database. With the new database structure, this makes sense as the output should be removed from the database when it is spent. But, if you look a few lines down, you see that it only deletes the coin when it is marked as FRESH
. In the case the coin was FRESH
, SpendCoin
would delete the object on the first pass so the second pass the coin would not be found and thus it would return false. This triggers the assert
following the function call causing the node to shutdown.
If the coin was not FRESH
, the coin object itself is not deleted, but its contents are cleared. This means that the second time the input is seen, if the coin was not FRESH
, SpendCoin
would still return true as the object still exists in memory, which means that it passes the assert that follows the SpendCoin
(which caused the crash when the coin was not FRESH
). Then validation continues as normal, and the output this transaction created is added to the UTXO database, which means that money that shouldn't exist now exists in the UTXO database.
So now the question is, when are UTXOs marked as FRESH
? They are marked FRESH
when they are added to the UTXO database. But the UTXO database is still only in memory (as a cache). When it is saved to disk, the entries in memory are then no longer marked as FRESH
. This saving to disk happens after every block (as well as at other times, but that is not important).
Thus, if a miner has an output that was part of a transaction that has already confirmed, and he spends the output twice in the same transaction (so the transaction has two inputs that refer to the same output), and this transaction is not broadcast to the network but instead included in a block that he mines, he is able to create a new output that has twice the value of the output that he spent, thereby creating coins.
Why can't this be done by a non-miner?
The reason that this cannot be done by a non-miner is because transactions that are received outside of blocks are still checked for duplicate inputs. The transaction will be rejected as invalid and not added to the node's mempool, so the transaction will never get into a block. It is only transactions with duplicate inputs that get into blocks that trigger this vulnerability, and thus only miners can do this as they must knowingly insert an invalid transaction into their block.
Also, which forks are/were vulnerable?
Any fork whose software includes commit eecffe50efc3944d713c701fa375dacbf17fb7cf
. This would mean any software forked from or pulled in changes from Bitcoin Core after November 10th, 2016.
answered Sep 22 at 1:23
Andrew Chowâ¦
28.5k21960
28.5k21960
Would a node that receives the block as a compact block check for the duplicate?
â Murchâ¦
Sep 22 at 18:16
2
No, it would not. The transaction with the duplicate input would not be in the mempool so it would be sent along with the block (as part of ablocktxn
message). Such transactions are not run through the mempool acceptance code. Instead the block is reconstructed and run through the normal block acceptance code.
â Andrew Chowâ¦
Sep 22 at 19:04
Great write-up, thank you! It seems to me having a bool flag such asfCheckDuplicateInputs
seems pretty unfortunate. It is quite easy to set it to an invalid value. I'm just wondering if we shouldn't be more explicit and verbose in those critical parts
â tsusanka
Sep 26 at 7:54
add a comment |Â
Would a node that receives the block as a compact block check for the duplicate?
â Murchâ¦
Sep 22 at 18:16
2
No, it would not. The transaction with the duplicate input would not be in the mempool so it would be sent along with the block (as part of ablocktxn
message). Such transactions are not run through the mempool acceptance code. Instead the block is reconstructed and run through the normal block acceptance code.
â Andrew Chowâ¦
Sep 22 at 19:04
Great write-up, thank you! It seems to me having a bool flag such asfCheckDuplicateInputs
seems pretty unfortunate. It is quite easy to set it to an invalid value. I'm just wondering if we shouldn't be more explicit and verbose in those critical parts
â tsusanka
Sep 26 at 7:54
Would a node that receives the block as a compact block check for the duplicate?
â Murchâ¦
Sep 22 at 18:16
Would a node that receives the block as a compact block check for the duplicate?
â Murchâ¦
Sep 22 at 18:16
2
2
No, it would not. The transaction with the duplicate input would not be in the mempool so it would be sent along with the block (as part of a
blocktxn
message). Such transactions are not run through the mempool acceptance code. Instead the block is reconstructed and run through the normal block acceptance code.â Andrew Chowâ¦
Sep 22 at 19:04
No, it would not. The transaction with the duplicate input would not be in the mempool so it would be sent along with the block (as part of a
blocktxn
message). Such transactions are not run through the mempool acceptance code. Instead the block is reconstructed and run through the normal block acceptance code.â Andrew Chowâ¦
Sep 22 at 19:04
Great write-up, thank you! It seems to me having a bool flag such as
fCheckDuplicateInputs
seems pretty unfortunate. It is quite easy to set it to an invalid value. I'm just wondering if we shouldn't be more explicit and verbose in those critical partsâ tsusanka
Sep 26 at 7:54
Great write-up, thank you! It seems to me having a bool flag such as
fCheckDuplicateInputs
seems pretty unfortunate. It is quite easy to set it to an invalid value. I'm just wondering if we shouldn't be more explicit and verbose in those critical partsâ tsusanka
Sep 26 at 7:54
add a comment |Â
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fbitcoin.stackexchange.com%2fquestions%2f79481%2fhow-does-the-most-recently-found-critical-vulnerability-cve-2018-17144-work%23new-answer', 'question_page');
);
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password