Bug #16259 SQLGetData, SQLBindCol, SQLBindParameter make assumptions about buffer sizes
Submitted: 6 Jan 2006 19:01 Modified: 8 Mar 2007 2:30
Reporter: tom hindle
Status: Not a Bug
Category:Connector/ODBC Severity:S2 (Serious)
Version:3.51.12 OS:IBM AIX (AIX 5.2, 64-bit)
Assigned to: Target Version:

[6 Jan 2006 19:01] tom hindle
Description:
When binding SQL_C_SLONG (and other integer types), the SQLGetData(), SQLBindCol and
SQLBindParameter routines blanketly ignore the buffer length argument.

Each assumes that the data pointer is to a long host variable which isn't strictly the
case according to the ODBC spec (and certainly how the system I'm working on uses the
ODBC interface). For example, if I pass a pointer to an integer, the cast (from
driver/results.c): 

  *(long *)rgbValue = (long)atol(value)

is extremely dangerous. Particularly on 64-bit systems where the size of integer and long
are not consistent. This happens to walk all over memory. It is essential to pay attention
to the buffer size indicator if there is any possibility of variance in the input type.

How to repeat:
 Just a simple call such as: 

  int i, count;

  SQLGetData(some_stmt_handle,1,SQL_C_SLONG,&i,sizeof(int),&count);
[18 Jul 2006 9:41] Sveta Smirnova
test case

Attachment: bug16259.c (text/plain), 1.69 KiB.

[18 Jul 2006 9:49] Sveta Smirnova
I can not raise error using test case attached to the bug. Please, look into it and if it
is not correct, provide correct test case. Thank you.
[18 Jul 2006 10:56] tom hindle
The testcase will only demonstrate a problem if sizeof(int)!=sizeof(long)

Which is the case on (at least) some 64bit systems.

Your test case needs to be run on a 64bit system, where long and int sizes differ.
[18 Jul 2006 11:17] Sveta Smirnova
But it runs on 64-bit system without problems. So I steel need test case from you.
[18 Jul 2006 11:43] tom hindle
testcase showing basic problem.

Attachment: main64bittest.c (text/x-csrc), 520 bytes.

[18 Jul 2006 11:46] tom hindle
Modifyied your testcase to try and show the problem

Attachment: bug16259.c (text/x-csrc), 1.75 KiB.

[24 Jul 2006 14:38] tom hindle
Just to confirm (as status is still Need Feedback) testcases have been attached.
[24 Jul 2006 20:13] Sveta Smirnova
Thank you for the reminder and test cases. I am working for the problem.
[24 Jul 2006 22:14] Sveta Smirnova
Verified on 64-bit Linux using test provided by reporter:

 Connecting to 'myodbc3' with user name 'root'...
bug16259_2(5431): unaligned access to 0x60000fffffffae0c, ip=0x200000000006a731
1
j should be 500 j == 500
bug16259_2(5431): unaligned access to 0x60000fffffffae0c, ip=0x200000000006a731
2
j should be 500 j == 500
bug16259_2(5431): unaligned access to 0x60000fffffffae0c, ip=0x200000000006a731
3
j should be 500 j == 500
bug16259_2(5431): unaligned access to 0x60000fffffffae0c, ip=0x200000000006a731
4
j should be 500 j == 500
5
j should be 500 j == 500
6
j should be 500 j == 500
7
j should be 500 j == 500
[13 Feb 2007 2:45] Jim Winstead
The BufferLength parameter should be ignored when handling fixed size data. Here's a quote
from the SQLGetData() documentation from MSDN:

 When the driver returns fixed-length data, such as an integer or a date structure, the
driver ignores BufferLength and assumes the buffer is large enough to hold the data. It
is therefore important for the application to allocate a large enough buffer for
fixed-length data or the driver will write past the end of the buffer.

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/odbc/htm/odbcsqlgetdata.a...

SQLBindCol() and SQLBindParameter() have similar text. IBM's DB/2 ODBC documentation also
indicates that BufferLength is ignored for fixed-length data.

This isn't to say there have not been problems in this area with C/ODBC 3.51. Until
recently (and possibly still), it often assumed that the argument of type SQL_C_LONG was
actually of the C long type, but it should have been SQLINTEGER (which may or may not be
a C long).