C language arithmetic operator overbounds problem solution

  • 2020-04-01 21:25:13
  • OfStack

A large number of security vulnerabilities are caused by the subtle details of computer arithmetic operations. Specific C language, such as the conversion between signed and unsigned Numbers, and the crossing of arithmetic operations, can lead to unpredictable errors and security vulnerabilities, and there are numerous specific cases.

As a system programmer, it is necessary to have a deep understanding of these details.

Although this code through a lot of tests, but I still can't guarantee the correctness of the code, hope you correct).
The principle of explanation is "pendulum theorem, no proof, write code"
Problem 1: the problem of crossing the boundary of the addition of unsigned Numbers
[theorem]

< img Alt = "" border = 0 SRC =" / / files.jb51.net/file_images/article/201211/2012111411484830.png ">
[understanding]
This theorem is easier and more acceptable. I won't explain it.

 
 
int uadd_ok(unsigned int x, unsigned int y) 
{ 
return !(x+y < x); 
} 

Problem two: the problem of subtracting unsigned Numbers
[theorem]

< img Alt = "" border = 0 SRC =" / / files.jb51.net/file_images/article/201211/2012111411484831.png ">

< img Alt = "" border = 0 SRC =" / / files.jb51.net/file_images/article/201211/2012111411484832.png ">


[understanding]
1. There is no subtraction in the computer, x-y = x+(-y), here is the addition inverse of y.
< img Alt = "" border = 0 SRC =" / / files.jb51.net/file_images/article/201211/2012111411484833.png ">
C language guarantee -x = ~x+1; You can verify that this approach is equivalent to the above formula.
4. S is equal to x minus y is equal to x plus minus y. Uadd_ok (x, y).

< img Alt = "" border = 0 SRC =" / / files.jb51.net/file_images/article/201211/2012111411484834.png ">

 
 
int usub_ok(unsigned int x, unsigned int y) 
{ 
return !y || !uadd_ok(x, -y); 
} 

Problem 3: the multiplication problem of unsigned Numbers
[theorem]

< img Alt = "" border = 0 SRC =" / / files.jb51.net/file_images/article/201211/2012111411484835.png ">
[understanding]
Equivalent conditions can be derived from each other.

 
 
int umul_ok(unsigned int x, unsigned int y) 
{ 
unsigned int p = x * y; 
return !x || p/x==y; 
} 

Problem 4: the problem of crossing the bounds of signed Numbers
[theorem]
For two signed Numbers x,y, the equivalent condition for crossing the line is that x,y is negative, x plus y is positive or x,y is positive, x plus y is negative.
[understanding]
This is an easy theorem.
 
 
int tadd_ok(int x, int y) 
{ 
return !(x<0&&y<0&&x+y>0 || x>0&&y>0&&x+y<0); 
} 

Problem 5: subtractive problem of signed Numbers
[theorem]

< img Alt = "" border = 0 SRC =" / / files.jb51.net/file_images/article/201211/2012111411484836.png ">

< img Alt = "" border = 0 SRC =" / / files.jb51.net/file_images/article/201211/2012111411484837.png ">
[understanding]
Same as unsigned subtraction, except the definition of the additive inverse is different, but the bit pattern is the same.

 
 
int tsub_ok(int x, int y) 
{ 
  #if 0 
  if (y == INT_MIN) 
  return x<0; 
  else 
  return tadd_ok(x, -y); 
  #endif 
  return y==INT_MIN&&x<0 || y!=INT_MIN&&tadd_ok(x, -y); 
} 

Problem 6: crossing the bounds of multiplication of signed Numbers
[theorem]
It's exactly the same as unsigned multiplication.
 
 
int tmul_ok(int x, int y) 
{ 
#if 0 
int p = x * y; 
return !x || p/x==y; 
#endif 
return umul_ok(x, y);  
} 


Related articles: