[Nasm-bugs] [Bug 3392609] Stack buffer overflow found when specifying addresses and offset
noreply-nasm at gorcunov.org
noreply-nasm at gorcunov.org
Mon Sep 16 10:59:42 PDT 2019
https://bugzilla.nasm.us/show_bug.cgi?id=3392609
T Turek <tureqsec at gmail.com> changed:
What |Removed |Added
----------------------------------------------------------------------------
CC| |tureqsec at gmail.com
--- Comment #1 from T Turek <tureqsec at gmail.com> ---
Hi again,
I managed to analyze this issue a bit to try and help out with a fix. I was not
able to reproduce the issue when debugging with gdb and I'm still not sure why.
I removed the -O2 flag to prevent the code doing weird things and managed to
get a different output (there is different behaviour observed depending on this
flag):
```
$ ./ndisasm -u -o148h -s23eh -k 0,149h test.bin
4141414141414141 skipping 0x149 bytes
Segmentation fault (core dumped)
```
I verified in code that I have overwritten the offset variable. Digging further
I can see the following:
```
...
p = q = buffer;
// nextsync is set to 0 here, offset is 328 and synclen 329
nextsync = next_sync(offset, &synclen);
do {
// to_read is set to 64 here (buffer - p is 0 and sizeof(buffer) is 64)
uint32_t to_read = buffer + sizeof(buffer) - p;
if ((nextsync || synclen) &&
to_read > nextsync - offset - (p - q))
// here to_read is recalculated to -328 and since
// to_read is uint32_t this becomes a huge number
to_read = nextsync - offset - (p - q);
if (to_read) {
// since to_read is huge, whole file is read, overwriting memory
lenread = fread(p, 1, to_read, fp);
if (lenread == 0)
eof = true; /* help along systems with bad feof */
} else
lenread = 0;
p += lenread;
...
```
I'm not 100% sure what the cleanest fix for this would be, the quickest fix
I've made is to put a check for `nextsync - offset - (p - q))` before fread is
executed. Something like:
```
...
p = q = buffer;
nextsync = next_sync(offset, &synclen);
do {
uint32_t to_read = buffer + sizeof(buffer) - p;
// added code starts here
int32_t check = nextsync - offset - (p - q);
if (check < 0) {
break;
}
// added code ends here
if ((nextsync || synclen) &&
to_read > check)
to_read = check;
if (to_read) {
lenread = fread(p, 1, to_read, fp);
...
```
Quick test shows that this approach would fix the issue but I'm not completely
sure if this breaks something else.
--
You are receiving this mail because:
You are watching all bug changes.
You are on the CC list for the bug.
More information about the Nasm-bugs
mailing list