colefichter/erlang-odbc-tips — pull request #1 by benmmurphy (2014-10-14 09:56:00+00:00)
Title: add information about large column truncation

also, i think when dealing with the buffer overflow problem it is better to do something like: {{sql_varchar, byte_size(X) + 1, X} rather than truncation. This +1 is also important because I compiled odbcserver with address sanitizer support and if you pass in a string of size 6 and set sql_varchar to 6 then it overflows one byte of memory somewhere. I reported this problem to the erlang team so they may have fixed it but I think odbc support is kind of very low priority for them.

21> odbc:param_query(Connection, "select ?", [{{sql_varchar, 1}, [<<"a">>]}]).

=================================================================
==20755== ERROR: AddressSanitizer: heap-buffer-overflow on address
0x60040000a9f0 at pc 0x7face87e3e29 bp 0x7fffa37651d0 sp
0x7fffa37651a8 WRITE of size 3 at 0x60040000a9f0 thread T0

17> odbc:param_query(Connection, "select ?", [{{sql_varchar, 0}, [<<>>]}]).

===================================================================20715==
ERROR: AddressSanitizer: heap-buffer-overflow on address
0x60040000ab10 at pc 0x7fe5faaafe29 bp 0x7fffff09dac0 sp
0x7fffff09da98 WRITE of size 2 at 0x60040000ab10 thread T0

but if you add an extra byte to the size it is fine:

24> odbc:param_query(Connection, "select ?", [{{sql_varchar, 2}, [<<"a">>]}]).

{selected,["?column?"],[{<<"a">>}]}

I would also strongly recommend having all your code paths go through functions like query(Query, Params) where params are raw binaries/integers/etc and then the query function adds the annotations for sql_varchar/sql_integer/etc because if you screw up the sql_varchar annotation then you have a security problem on your hands.

But whatever you decide to do in regards to sql_varchar/sql_wlongvarchar truncation or sizing I would strongly recommend compiling odbcserver with address sanitizer (https://code.google.com/p/address-sanitizer/) support and then sending through the boundary cases to make sure you are not corrupting memory.

I would also recommend using {binary_strings, on} and using utf8 erlang binaries everywhere but this is coming from postgresql. I'm not sure how easy this is to do for other databases.