Skip to navigation
   
Dave F's Blog
Putting a Stop to Hanging with Safe Copying

By Dave F in Reader

Posted in Coding, Security on May 15, 2009 at 2:36 pm

Permalink | Author Profile

Irritating isn’t it, when a program mysteriously sits there like a sulking teenager, refusing to even acknowledge your presence however hard you click, type or shout?
I’ve just written one of those apparently. In the interests of world peace and understanding I’ll explain how it can happen - “understanding is the first thing, it means so much to me” as Van Morrison might say.
In my experience the most common programming bugs are to do with buffer over runs and threads. Threading issues are a bit more recent and a bit more tricky to handle. Two (or more) threads execute (virtually or literally) simultaneously which can cause more chaos than I want to think about here but imagine one thread has locked data the other needs and won’t let go until has another piece of data, thread two has that locked and won’t go until it gets the first piece - deadlock (and a hang).
Buffer over runs are old and common bugs in coding. They most often cause crashes but can be utilities by malignant (or I suppose, benign) hackers so we are now encouraged to use “safe” routines that check the size of a receive buffer when copying data. You may think “That’s clever, how do they do that?” In the main they aren’t clever, they just check what you tell them to check so they can still be wrong, the good thing is they tend to error during development so are fixed.
eg
strcpy(newbuf, oldbuf);
works fine until oldbuf happens to be bigger than newbuf which may not happen until some user does something the programmer never thought of.
strcpy_s(newbuf, newbuf_size, oldbuf);
will go wrong immediately if newbuf_size if wrong & will just truncate the copy if oldbuf is bigger. Job done.
How can over runs be used by hackers? If you over run newbuf and newbuf is a created on the stack (ie local variable which most things are) then you can write over the stack including the return address making the program return to the address you want not where it came from. If you are clever enough to get it to return to a data area and you have loaded the data area with code the program is suddenly executing your code. Of course you don’t need to be clever enough to write that kind of thing, just clever enough to use a hackers toolkit that does it for you.
Normally then over runs cause crashes by writing data over other data which confuses the program or writing a random return address so the program starts executing gibberish.
So how did I write a hanging program?
sub (int *from){
    int to[10];
    int i;
    for (i=0; from[i]; i++)
            to[i] = from[i];
    etc…
}
In this case when the buffer over runs it writes into int “i” so if “from” contains 11 values of 5 i goes
0,1,2,3,4,5,6,78,9 5 (contents of from[10]), 6,7,8,9, 5, 6,7,8,9, 5,…..
and so on until someone puts it out of its misery.
If “from[10]” contains > 10 then the loop may end after it has written data to all sorts of random places. That’s why I’m usually better than to write such naff code. My fix has was…
#define MAX_FROM_LEN 10
sub (int *from){

    int to[MAX_FROM_LEN];
    int i;
    for (i=0;  i<MAX_FROM_LEN && from[i]; i++)
            to[i] = from[i];
    etc…
}

12345
Not yet rated
Loading ... Loading ...

Previous Post | Next Post

 
 
Comments
This article has no comments yet.

Make a comment

* required

* required

We stop spam using reCaptcha.
Type the words below and click Submit Comment.

Advertisement