Re: safe strcpy()?

From: Michal Zalewski (lcamtufat_private)
Date: Tue Jan 28 2003 - 01:14:37 PST

  • Next message: Ed Carp: "Re: safe strcpy()?"

    On Tue, 28 Jan 2003, Ed Carp wrote:
    
    > This lef me to go back to my C textbooks (which I hadn't liiked in
    > almost 20 years!), and start looking for a way to figure out how to
    > determine how much space was allocated to a string.  I was rather
    > surprised to find that I couldn't find such an animal!  Am I missing
    > something here?
    
    Not really. C itself does not provide any built-in mechanism for passing
    sizes of buffers or other objects. Sizeof() is merely replaced with the
    storage size of whatever you passed to it during the compilation, and is
    not a runtime mechanism for determining the size of an object you point
    to.
    
    > I'm not interested in manual manipulation of code, or suggestions on
    > changing coding style - there should be a way in the language to
    > determine the size of an object at runtime.
    
    No. C is a fairly low-level language. There are some versions of C that
    generate code with range checking and such, but it's not very common (and
    not always as effective as in other languages).
    
    You think what made C co popular?;-) If you write your code in range
    checked, strong typed language, you get some strange errors all the
    time... if you write it in C, it runs, *maybe* sometimes behaves strangely
    because some variable gets overwritten, but hey, good enough to release
    ;-)
    
    For dynamically allocated memory, you might want to use
    malloc_usable_size() in glibc, or a similar mechanism available for your
    OS, but that works well only if the buffer is a separate chunk. It's a
    limited, non-portable and often dangerous approach, and most likely
    requires some coding style changes anyway, just to keep all buffers in
    separate chunks.
    
    There are several interesting ways to prevent the problem without making
    major changes to the code, however. One of better ideas I've seen is to
    register buffer sizes when buffers are created. It takes few more lines
    when you create an object, but this is the only effort you need to make.
    Buffers are later deregistered from your own free(), for heap memory - and
    your own function epilogue, for stack. With some help from the compiler
    and linker, two last steps involve no changes to your existing code. If
    your code uses mapped memory, you might also want to cover munmap and
    such.
    
    You just call register_buf() whenever you create an array, a structure or
    such. Its address, length and element size would be stored, so that you
    can query for a buffer at any time, and perhaps decide, based on element
    size, if its suitable for the operation you are about to perform (so that
    when you have a number of buffers inside an array, and you only added the
    array to implement index range checking, but forgot to add single buffers,
    your code would not overwrite other elements when modifying one, but
    rather bail out because of element size mismatch).
    
    The approach is not perfect, but can be quite helpful.
    
    -- 
    ------------------------- bash$ :(){ :|:&};: --
     Michal Zalewski * [http://lcamtuf.coredump.cx]
        Did you know that clones never use mirrors?
    --------------------------- 2003-01-28 00:41 --
    



    This archive was generated by hypermail 2b30 : Tue Jan 28 2003 - 09:13:48 PST