"SfR Fresh" - the SfR Freeware/Shareware Archive

Member "dovecot-1.0.15/doc/securecoding.txt" of archive dovecot-1.0.15.tar.gz:


As a special service "SfR Fresh" has tried to format the requested source page into HTML format using source code syntax highlighting with prefixed line numbers. Alternatively you can here view or download the uninterpreted source code file. That can be also achieved for any archive member file by clicking within an archive contents listing on the first character of the file(path) respectively on the according byte size field.
    1 Simplicity provides security. The more you have to remember to maintain
    2 security the easier it is to forget something.
    3 
    4 
    5 Use Multiple Layers of Security
    6 -------------------------------
    7 
    8 Input validation is useful to prevent clients from taking too much server
    9 resources. Add the restrictions only where it's useful. For example a
   10 simple "maximum line length" will limit the length of pretty much all
   11 possible client input.
   12 
   13 Don't rely on input validation. Maybe you missed something. Maybe someone 
   14 calls your function somewhere else where you didn't originally intend it.
   15 Maybe someone makes the input validation less restrictive for some reason.
   16 Point is, it's not an excuse to cause a security hole just because input
   17 wasn't what you expected it to be.
   18 
   19 Don't trust memory. If code somewhere overflowed a buffer, don't make it
   20 easier to exploit it. For example if you have code:
   21 
   22   static char staticbuf[100];
   23   ..
   24   char stackbuf[100];
   25   strcpy(stackbuf, staticbuf);
   26 
   27 Just because staticbuf was declared as [100], it doesn't mean it couldn't
   28 contain more data. Overflowing static buffers can't be directly exploited,
   29 but the strcpy() overflowing stackbuf makes it possible. Always copy data
   30 with bounds checking.
   31 
   32 
   33 Prevent Buffer Overflows
   34 ------------------------
   35 
   36 Avoid writing to buffers directly. Write everything through buffer API
   37 (lib/buffer.h) which guarantees protection against buffer overflows.
   38 There are various safe string APIs as well (lib/str.h, lib/strfuncs.h).
   39 Dovecot also provides a type safe array API (lib/array.h).
   40 
   41 If you do write to buffers directly, mark the code with /* @UNSAFE */
   42 unless it's _obviously_ safe. Only obviously safe code is calling a
   43 function with (buffer, sizeof(buffer)) parameters. If you do _any_
   44 calculations with buffer size, mark it unsafe.
   45 
   46 Use const with buffers whenever you can. It guarantees that you can't
   47 accidentally modify it.
   48 
   49 Use "char *" only for NUL-terminated strings. Use "unsigned char *"
   50 if it's not guaranteed to be NUL-terminated.
   51 
   52 
   53 Avoid free()
   54 ------------
   55 
   56 Accessing freed memory is the most difficult problem to solve with C code.
   57 Only real solution is to use garbage collector, but it's not possible to
   58 write a portable GC without radical changes in how you write code.
   59 
   60 I've added support for Boehm GC, but it doesn't seem to be working very
   61 well currently. In any case I'd rather not make it required.
   62 
   63 There are a few ways to avoid most free() calls however: data stack and
   64 memory pools.
   65 
   66 Data stack works in somewhat similiar way to C's control stack. alloca() is
   67 quite near to what it does, but there's one major difference: Stack frames
   68 are explicitly defined, so functions can return values allocated from data
   69 stack. t_strdup_printf() call is an excellent example of why this is
   70 useful. Rather than creating some arbitrary sized buffer and using
   71 snprintf() which may truncate the value, you can just use t_strdup_printf()
   72 without worrying about buffer sizes being large enough.
   73 
   74 Try to keep the allocations from data stack small, since the data stack's
   75 highest memory usage size is kept for the rest of the process's lifetime.
   76 The initial data stack size is 32kB and it should be enough in normal use.
   77 See lib/data-stack.h.
   78 
   79 Memory pools are useful when you have to construct an object from multiple
   80 pieces and you can free it all at once. Actually Dovecot's Memory Pool API
   81 is just an abstract class for allocating memory. There's system_pool for
   82 allocating memory with calloc(), realloc() and free() and you can create a
   83 pool to allocate memory from data stack. If your function needs to allocate
   84 memory for multiple objects, you may want to take struct pool as parameter
   85 to allow caller to specify where the memory is allocated from.
   86 See lib/mempool.h
   87 
   88 
   89 Deinitialize safely
   90 -------------------
   91 
   92 Whenever you free a pointer, set it to NULL. That way if you accidentally
   93 try to free it again, it's less likely to cause a security hole. Dovecot
   94 does this automatically with most of its free() calls, but you should also
   95 make it a habit of making all your _destroy() functions take a
   96 pointer-to-pointer parameter which you set to NULL.
   97 
   98 Don't Keep Secrets
   99 ------------------
  100 
  101 We don't do anything special to protect ourself against read access buffer
  102 overflows, so don't store anything sensitive in memory. We use multiple
  103 processes to protect sensitive information between users.
  104 
  105 When dealing with passwords and such, erase them from memory after you
  106 don't need it anymore. Note that such memset() may be optimized away by
  107 compiler, use safe_memset().
  108 
  109 
  110 Use GCC Extensions
  111 ------------------
  112 
  113 GCC makes it easy to catch some potential errors:
  114 
  115 Format string vulnerabilities can be prevented by marking all functions
  116 using format strings with __attr_format__() and __attr_format_arg__()
  117 macros and using -Wformat=2 GCC option.
  118 
  119 -W option checks that you don't compare signed and unsigned variables.
  120 
  121 I hope GCC will later emit a warning whenever there's potential integer
  122 truncation. -Wconversion kind of does that, but it's not really meant for
  123 it and it gives too many other useless warnings.
  124 
  125 
  126 Use union Safely
  127 ----------------
  128 
  129 Suppose there was code:
  130 
  131 union {
  132    unsigned int number;
  133    char *str;
  134 } u;
  135 
  136 If it was possible for user to set number arbitrarily, but access the union
  137 as string it'd be possible to read or write arbitrary memory locations.
  138 
  139 There's two ways to handle this. First would be to avoid union entirely and
  140 use a struct instead. You don't really need the extra few bytes of memory
  141 that union saves.
  142 
  143 Another way is to access the union only through macro that verifies that
  144 you're accessing it correctly. See IMAP_ARG_*() macros in
  145 lib-imap/imap-parser.h.