[Celes Security Service] Director Zhang’s Discussion on Safety Issue 1

CelesOS
5 min readDec 10, 2018

--

With the development of CelesOS, the CelesOS’s main network has made considerable progress. CelesOS is a blockchain operating system that embraces regulation and is suitable for regulators, financial institutions and users to access, and the security problem has always been a key area for CelesOS research and development team .

“In the current mainstream public blockchain, the security problems frequently occur: the private key of account was stolen and dapp is attacked by hackers…

An average of 1.5 projects in a public blockchain are hacked every week according to a security company

As the basis of blockchain technology, “security” brings people a sense of trust and a good prospect for the development of blockchain technology.

Since the release of the first weekly issue of CelesOS, engineers have been fighting against the security bugs of CelesOS and have also summed up a set of professional experience to solve the public blockchain bugs based on their vast experience.

From time to time director Zhang of CelesOS Security Bureau will analysis the bugs in the development of the public blockchain for everyone and share some solutions from this week.

May there be no bugs in the world.

Please fasten your seat belts. Here we go!

With the blockchain becoming more and more popular, various business contracts have showed, but the ensuing security problems have sounded alarm bells to developers again and again. As an emerging technology, there will be a lot of security problems in its early stage, which is inevitable. On the other hand, the exposure of security problems will also promote the better development of blockchain, and eventually lay a good foundation for the stability and maturity of blockchain.

As a programmer or engineer for many years, it is impossible to count how much code I have written, but I can tell you responsibly that I have spent 80% to 90% of my time dealing with the logic of errors and exceptions, which makes me tired and painful. But then I was relieved, because I knew it was impossible to write bug-free programs in my life, which does not mean that we ignore the existence of bugs. We should constantly summarize and learn from experience so that there will be fewer and fewer bugs. Let’s analyze the problem of data overflow in the contract. I hope it will be helpful to you.

Let’s look at a simple code first:

int main(int argc, const char * argv[]) {

int first = 2;

int second = 8;

int result = first * second;

std::cout << result << std::endl;

return 0;

}

These lines of code are very simple, and nothing else happens. Let’s revise it a little bit:

int main(int argc, const char * argv[]) {

int first;

int second;

std::cin >> first;

std::cin >> second;

int result = first * second;

std::cout << result << std::endl;

return 0;

}

int result = first * second;This sentence will take the overflow problem into account,INT_MAX = 2³¹-1,

INT_MIN= -2³¹.Therefore, judgment must be added here to deal with the overflow problem.

So that’s what we should deal with, right?

int main(int argc, const char * argv[]) {

int first;

int second;

std::cin >> first;

std::cin >> second;

int result = first * second;

eosio_assert(result >= INT_MIN,”multiplication underflow”);

eosio_assert(result <= INT_MAX,”multiplication overflow”);

std::cout << result << std::endl;

return 0;

}

Unfortunately, this still cannot achieve our goal! Because if there is an overflow, it will also be in the range of [INT_MAX,INT_MIN]

Well, let’s see if there are other ways to deal with the overflow problem.

int main(int argc, const char * argv[]) {

int first;

int second;

std::cin >> first;

std::cin >> second;

eosio_assert(second == 0 || (first * second)/second == first,”multiplication overflow or underflow”);

int result = first * second;

std::cout << result << std::endl;

return 0;

}

How about writing like this? Hit the run button and input values. Well, that’s what we want!

But if it is an EOS contract, there is still a problem in writing it like this! Why? Don’t worry! Here is the explanation of the problem written like this.

Because EOS contracts have to be translated into wasm before it can be executed, the current code in c++ is compiled with clang, and the optimization level of O3 is adopted by default. So this code “eosio_assert(second == 0 || (first * second)/second ==first,”multiplication overflow or underflow”); ” could be translated as “(call $eosio_assert (i32.const 1) (i32.const 224)),” that is, this sentence has always been true, so it has not reached the result of judgment. If you change the optimization level to O0, there will be no problem with this code.

Let’s look at the early overflow problems and solutions in EOS source code.

asset& operator*=( int64_t a ) {

eosio_assert( a == 0 || (amount * a) / a == amount, “multiplication overflow or underflow” );

eosio_assert( -max_amount <= amount, “multiplication underflow” );

eosio_assert( amount <= max_amount, “multiplication overflow” );

amount *= a;

return *this;

}

Obviously, there are some errors in the above code. Let’s take a look at the modified code.

asset&operator*=( int64_t a ) {

int128_t tmp = (int128_t)amount * (int128_t)a;

eosio_assert( tmp <= max_amount, “multiplication overflow” );

eosio_assert( tmp >= -max_amount, “multiplication underflow” );

amount = (int64_t)tmp;

return *this;

}

int128_t is used here as an auxiliary to determine whether int64_t overflows. So if there is no larger data type, how can we deal with this problem better? Let’s see whether the following code can solve our problem.

ator*=( int64_t a ) {

if(a != 0){

int64_t temp = (amount * a)/a;

eosio_assert(temp == amount, “multiplication overflow or underflow” );

}

amount *= a;

return *this;

}

▲ Note: This code has not been actually tested

When you are using operators in contracts, it is better to use some types provided by the system (although the system is sometimes not so reliable), such as asset here.

We should be very careful in coding, but we shall make bold guesses about some ambiguous issues and carefully verify them. That is why we’d rather kill all just for one!

Finally, I hope this article will be helpful to you.

--

--

CelesOS

CelesOS is an innovative public chain driven by financial services/applications and providing access for regulators and policy makers.