A little about my experience with off by one bugs.
One of the most common bugs I find when reverse engineering is off by one bugs. While they can have devastating consequences, they can also result in minor problems that cannot be exploited.
The below example details a bug I recently found in the HTTP proxy service of Trend IWSS (web security suite). This bug does not appear to have any exploitable conditions as it gets allocated to whatever the length of the string is. You could probably make the allocator fail to allocate (really big string), which would result in a null ptr and if it is not checked before use, it would result in an access violation.
The bug below is due to an off by one when allocating memory prior to a _snprintf call.
Prototype: parse_user_agent_header(char const *):
get string length:
.text:10001CD0 mov cl, [eax]
.text:10001CD2 add eax, 1
.text:10001CD5 test cl, cl
.text:10001CD7 jnz short loc_10001CD0
.text:10001CD9 sub eax, esi
.text:10001CDB cmp eax, 512 ; do if less than 512 characters in length
.text:10001CE0 jnb short loc_10001D4F
off by one:
.text:10001CE3 push edx
.text:10001CE4 push offset Format ; "%s"
.text:10001CE9 lea eax, [esp+21Ch+Str]
.text:10001CED push 512 ; Count
.text:10001CF2 push eax ; Dest
.text:10001CF3 call ds:_snprintf ; off by one. You can supply 512 chars.
.text:10001CF3 ; Therefore overwrites the null byte at the end.
The C code for this would look something like:
#define MAX_BUF_LEN 512
_snprintf(buff2, MAX_BUF_LEN, "%s", buff);
In the past i've found these types of bugs in a number of products such as Oracle's Web server (shipped with many Oracle products) and uTorrent.