Closed matthew-wozniczka closed 2 years ago
I think this could lead to a buffer overflow, even if not using parameter arrays
@smalinin @pkleef @openlink -- Please take a look at this!
@smalinin @pkleef @openlink -- Please take a look at this!
We are open to contributions from the public here.
@matthew-wozniczka,
Would you consider making a patch and pull request, to accelerate resolution?
/cc @smalinin @pkleef @openlink
Fixed, patch will be in Git soon.
Patch was committed
I've been debugging some new test failures when using iODBC 3.52.15, and in one scenario, I bind 1 SQL_C_WCHAR parameter, with a paramset size of 4, and a buffer size of 8 (i.e. 2 UTF32 characters). Each paramset contains a single-character, null terminated string, with the length indicators all set to SQL_NTS.
I've found that the new version (before we only used 3.52.8 or older) has some logic for converting parameter data before/after calling into the actual driver (I'm not sure why it's needed for this case, as iODBC itself detects that the driver encoding matches the DM encoding, i.e. UTF32), and while 'converting' (i.e. doing seemingly useless copies) the value of the parameter in the first parameter set, it overwrites the first character of the second parameter set's value with a null-terminator, causing the driver to see that value as an empty string.
I used a watchpoint to see exactly where it was happening:
https://github.com/openlink/iODBC/blob/79c7f572a7b5c4123ec3cc1dd29df1af61a3405f/iodbcinst/unicode.c#L2213 this logic is wrong, for my case, count==2, and the buffer contains 0x31 0x00 0x00 0x00 0x00 0x00 0x00 0x00, so on the second iteration of the loop, it exits, as it copied a 'null character'. But u4dst has already been incremented twice, even though len==1, so below it tries to write another null terminator, overwriting the first character of the next parameter set's value. This causes our driver to see the second parameter set's value as an empty string, instead of what it was actually set to by the application.