NetBSD-Bugs archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
lib/49683: Off-by-one comparison in ct_decode_string() leading to out of bound referrence
>Number: 49683
>Category: lib
>Synopsis: Off-by-one comparison in ct_decode_string() leading to out of bound referrence
>Confidential: no
>Severity: serious
>Priority: high
>Responsible: lib-bug-people
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Sat Feb 21 21:50:00 +0000 2015
>Originator: Amir Plivatsky
>Release: libedit 3.1 20141029
>Organization:
>Environment:
N/A
>Description:
When reading a line which has one more character then the previous one, an out of bound buffer reference happens.
The problem occurs due to an off-by-one comparison in ct_decode_string() (file chartype.c, rev 1.10 as of 20150221):
if (len > conv->wsize)
ct_conv_buff_resize(conv, (size_t)0, len + 1);
In ct_conv_buff_resize(), conv->wsize is set to the last argument, i.e to
len+1. This buffer and conv->wsize are retained over function calls. On the next entry to ct_decode_string() with a line length that is greater by one than in the previous entry to this function, there is a need for a bigger buffer (by 1). However, the check (quoted above) misses to detect that because it compares to the previous conv->wsize which is equal to the previous len+1, and thus now len==conv->wsize and a bigger buffer is not allocated.
>How-To-Repeat:
There is no real need to repeat the problem, since code inspection reveals the problem and the fix.
However, here is how I found it:
Due to an unrelated test, I got an history file with 2 lines, one of length 2481 and the other 2482. The application (which uses libedit) failed on heap-buffer-overflow on start-up when libedit tried to read this history file.
>Fix:
--- old/src/chartype.c 2015-02-21 23:39:29.306548291 +0200
+++ new/src/chartype.c 2015-02-21 23:39:33.218560054 +0200
@@ -123,7 +123,7 @@
len = ct_mbstowcs(NULL, s, (size_t)0);
if (len == (size_t)-1)
return NULL;
- if (len > conv->wsize)
+ if (len >= conv->wsize)
ct_conv_buff_resize(conv, (size_t)0, len + 1);
if (!conv->wbuff)
return NULL;
I actually implemented this fix and tested that it actually fixes this problem.
Home |
Main Index |
Thread Index |
Old Index