OS: solaris 5.8
Hardware: sun4u sparc SUNW,Sun-Fire-V440
FB 1.5.x (client on sun, server on sun/linux)
Python: 2.4.2
Kinterbasdb: 3.1.3, 3.2 (compiled from source)
Problem: several functions in _ki_conversion_from_db.c
exhibit the following unsafe pattern:
even the "64-bit" code does:
const LONG_LONG dataLL = *((LONG_LONG *) data);
That is, a (char*) is cast to (int/long/longlong*)
and then dereferenced without any alignment checks.
Depending on the current alignment of the pointer,
(and thus on the types/sizes of preceding fields)
this might cause unaligned memory access.
Which -depending on the platform- might
- work ok (if unaligned access is supported)
- cause overhead (access gets trapped&emulated)
- kill the application (Bus Error/SIGBUS)
We noticed this problem with kinterbasdb 3.1.3 and "fixed" it locally with code like this:
ISC_SHORT _short;
ISC_LONG _long;
long conv_long;
if (data_type == SQL_SHORT) {
memcpy( (char*)&_short, data, sizeof(_short));
conv_long= _short;
} else {
memcpy( (char*)&_long, data, sizeof(_long));
conv_long= _long;
}
but i hesitate to consider that a real fix,
because the unconditional copy would penalize
- alignment-agnostic platforms (i386?) and
- buffers that happen to be properly aligned.
the "ideal fix" would be a macro/inline that does
- nothing on "alignment-agnostic" platforms
- copy(-if-unaligned) on affected platforms
Best regards, S.K.
Logged In: YES
user_id=1858271
Originator: YES
Followup: the same thing happens in _kiconversion.c line 955..
case SQL_FLOAT:
result = conv_out_floating(*((float *) sqlvar->sqldata), dialect, scale);
break;
case SQL_DOUBLE:
case SQL_D_FLOAT:
result = conv_out_floating(*((double *) sqlvar->sqldata), dialect, scale);
break;