Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Feedback on analysis of code example (secure coding)

I have a piece of code from an assignment I am uncertain about. I feel confident that I know the answer, but I just want to double-check with the community incase there's something I forgot. The title is basically secure coding and the question is just to explain the results.

int main() {
   unsigned int i = 1;
   unsigned int c = 1;
   while (i > 0) {
     i = i*2;
     c++;
   }
   printf("%d\n", c);
   return 0;
}

My reasoning is this:

At first glance you could imagine the code would run forever, considering it's initialized to a positive value and ever increasing. This of course is wrong because eventually the value will grow so large it will cause an integer overflow. This in turn is not entirely true either, because eventally it will force the variable 'i' to be signed by making the last bit to 1 and therefore regarded as a negative number, therefore terminating the loop. So it is not writing to unallocated memory and therefore cause integer overflow, but rather violating the data type and therefore causing the loop to terminate.

I am quite sure this is the reason, but I just want to double check. Any opinions?

like image 522
KaiserJohaan Avatar asked Mar 02 '11 15:03

KaiserJohaan


2 Answers

No, unsigned int will never compare against zero as a signed number. The only chance for the loop to end is for the variable to become exactly zero.

The latter will surely happen once since you multiply by 2 (an even number) in each iteration and this causes a zero bit to be inserted from right (least meaningful bit), so after some number of iterations all non-zero bits will be "shifted out of the number" and it will become zero.

like image 145
sharptooth Avatar answered Nov 04 '22 11:11

sharptooth


There is no overflow when dealing with unsigned values. All calculations are done modulo (UINT_MAX + 1).

So, what happens is that the value by repeatedly multiplying by 2 you eventually wrap-around to zero ... and your loop stops

Suppose, for simplicity sake, that unsigned is 4 bits wide.

1 * 2 = 2 ==> 0b0010
2 * 2 = 4 ==> 0b0100
4 * 2 = 8 ==> 0b1000
8 * 2 = 0 ==> 0b0000
like image 44
pmg Avatar answered Nov 04 '22 10:11

pmg