UnixODBC realted question.

Все, что вы хотели знать о программизме, но боялись спросить.
Ответить
Аватара пользователя
Old_Tuzik
Житель
Сообщения: 795
Зарегистрирован: 28 авг 2007, 16:38
Контактная информация:

UnixODBC realted question.

Сообщение Old_Tuzik »

Интересно, сталкивался ли кто с проблемой run time check of SQLLEN size on Unix like (the ones that support UnixODBC) systems? С тех пор как ребята поменяли размер этого типа данных и забыли громко предупредить остальной мир об этом уже много воды утекло и многие компании теперь просто поставляют несколько своих драйверов с 32 bit SQLLEN and 64 bit SQLLEN но мне бы просто хотелось определить размер SQLLEN for Unix ODBC driver manager on the fly without reading the ODBC D.M. config and so on.
Для справки - люди спрашивают то же вопрос и довольно здраво размышляют про доступные варианты:

http://mailman.unixodbc.org/pipermail/u ... 01609.html

и собираются просто использовать latest build of UnixODBC to avoid the aforementioned ambiguity. К сожалению у меня такого выбора нет, поддерживать надо все версии UnixODBC и поэтому run time check of the size of SQLLEN seems to be the only way to proceed.
Аватара пользователя
aissp
Маньяк
Сообщения: 2710
Зарегистрирован: 07 ноя 2005, 09:51

Re: UnixODBC realted question.

Сообщение aissp »

Вот ето подойдет?

http://www.mail-archive.com/debian-bugs ... 37601.html

slencheck utility
Аватара пользователя
Old_Tuzik
Житель
Сообщения: 795
Зарегистрирован: 28 авг 2007, 16:38
Контактная информация:

Re: UnixODBC realted question.

Сообщение Old_Tuzik »

спасибо за инфу, не пойдет потому как я не хочу возиться с еще одним процессом (а в нектром сысле даже и не могу), а если бы хотел то мог просто сделать следующее:
odbcinst -j

и получить что то вроде:
nixODBC 2.2.14
SQLULEN Size.......: 8
SQLLEN Size........: 8
SQLSETPOSIROW Size.: 8

хотелось бы сделать проверку своими силами и налету. Есть одна идея по поводу проверки стека после вызова стандартной библиотечной функции использующей SQLLEN как параметер по ссылке - если мой код скомпилирован в ожидании 32 bit SQLLEN and underlying function believes that it deals with 64 bit SQLLEN it will unknowingly damage the stack - the only question is if I can catch it and properly recover
Аватара пользователя
aissp
Маньяк
Сообщения: 2710
Зарегистрирован: 07 ноя 2005, 09:51

Re: UnixODBC realted question.

Сообщение aissp »

ну стек оно тебе положим не поломает:

Код: Выделить всё

 struct qq
{
 uint32_t low;
 uint32_t high;
}

union qqq
{ qq first;
 uint64_t second;
}

qqq myQQ;

bad_func( (SQLLEN*)& myQQ);
если ошибешься то программа вылетит с ощибкой а со стеком ничего не случиться. (все ето если я тебя правильно понял конечно)
Аватара пользователя
Old_Tuzik
Житель
Сообщения: 795
Зарегистрирован: 28 авг 2007, 16:38
Контактная информация:

Re: UnixODBC realted question.

Сообщение Old_Tuzik »

aissp писал(а):ну стек оно тебе положим не поломает:
если ошибешься то программа вылетит с ощибкой а со стеком ничего не случиться. (все ето если я тебя правильно понял конечно)
Однозначного ответа тут не может быть потому как это очевидно зависит ом нескольких вещей - тип компилятора, byte order, type of build (release or debug) и прочее.
Пример:

bad_funct( SQLLEN* sl_xx)
{
...
memset (sl_xx, 0, sizeof (SQLLEN))

...
}

my_func(void)
{
UINT4 ui4_1; // because SQLLEN is declared as SQLINTEGER in older builds of UnixODBC
bad_funct( & ui4_1);
}

if the stack (again it depends on several diff. conditions) looks like this:

bottom of the stack
... garbage
... ui4_1
...RET ADDR
.. frame of prev. functions (caller)
top of the stack

then the return address will/can be set to 0 and as soon as my_func() returns, the app will crash.

Some compilers, especially in debug build will/can allocate additional buffer or just a single variable on the stack and check later if its state is ok - if it's overwritten then the stack is damaged, etc etc. This is the most common way to prevent buffer overflow type of attacks.

---
so my idea was as follows:

my_func(void)
{
UINT4 ui4_guard_0 = 0xAAAAAAAA;
UINT4 ui4_1;
UINT4 ui4_guard_1 = 0xBBBBBBBBB;
bad_funct( & ui4_1);
if ((ui4_guard_0 != 0xAAAAAAAA) || (ui4_guard_1 != 0xBBBBBBBBB))
"ups!";
}

but I must admit it did not work, the var. ui4_guard_0 / ui4_guard_1 were not overwritten - ok, it was somehow expected to happen.
Аватара пользователя
aissp
Маньяк
Сообщения: 2710
Зарегистрирован: 07 ноя 2005, 09:51

Re: UnixODBC realted question.

Сообщение aissp »

Не философствуя глубоко, я имел ввиду что если ту передаешь переменную намеренного больщего размера. в твоем примере
my_func:

char ui4_1[256]; //:) и гарды можешь прямо в массив записать я для етого union и прописал
bad_funct( & ui4_1);

соотвественно функция будет писать только по етому указателю и ничего со стеком не случится, а то что твои гарды не работают означает что функция ничего туда не прописала. (как я это понимаю)

проверить ето тоже легко, точку прерывания на изменения значения переменной которая передается в функцию - так пробовал? меняется? но насколько я помню все ети функции начинают работать если есть физический коннект к базе. (?)

удачи короче
Аватара пользователя
Old_Tuzik
Житель
Сообщения: 795
Зарегистрирован: 28 авг 2007, 16:38
Контактная информация:

Re: UnixODBC realted question.

Сообщение Old_Tuzik »

aissp писал(а): удачи короче
спсб, я решил найти slencheck (она почему то не присутвсует в UnixODBC install package и их репозитории, в инете все 2 упоминания, одно их них - твоя ссылка) и банально посмотреть как они сами проверяют размер этого типа данных. Если там на какой нибудь инсталяции линукса она у тебя найдется, можешь ты мне ее подошлешь?
aissp писал(а):проверить ето тоже легко, точку прерывания на изменения значения переменной которая передается в функцию - так пробовал? меняется?
значение меняется как если бы оно бы 32 битное и рядом стоящиие гард переменные - нет и это странно. Такое может быть если bad_funct рассматривает 64 битное число как 2 32 битных и зная что параметер не может превысить MAX_LONG устанавливает только LO 32 bit integer - таким образом они не трогают HI 32 bit integer and my spec. guard. variables are not overwritten.
Аватара пользователя
aissp
Маньяк
Сообщения: 2710
Зарегистрирован: 07 ноя 2005, 09:51

Re: UnixODBC realted question.

Сообщение aissp »

ну ссылку на билд на который ссылаются в письме я нашел:

http://fossies.org/linux/privat/unixODB ... re.tar.gz/

но чегой то чека там етого нету (ну или я не нашел) напиши етому Nick Gorham письмо, нехай выложит :)
Аватара пользователя
Old_Tuzik
Житель
Сообщения: 795
Зарегистрирован: 28 авг 2007, 16:38
Контактная информация:

Re: UnixODBC realted question.

Сообщение Old_Tuzik »

нашел сорсы от slencheck и ты только глянь что он делает:

Код: Выделить всё

   ret = SQLTables( hstmt, NULL, 0, NULL, 0, NULL, 0, NULL, 0 );
    if ( !SQL_SUCCEEDED( ret )) {
        show_error( henv, hdbc, hstmt, "SQLTables" );
        exit( -1 );
    }

    mem[ 0 ] = 0xde;
    mem[ 1 ] = 0xad;
    mem[ 2 ] = 0xbe;
    mem[ 3 ] = 0xef;
    mem[ 4 ] = 0xde;
    mem[ 5 ] = 0xad;
    mem[ 6 ] = 0xbe;
    mem[ 7 ] = 0xef;

    ret = SQLRowCount( hstmt, (SQLLEN*) mem );
    if ( !SQL_SUCCEEDED( ret )) {
        show_error( henv, hdbc, hstmt, "SQLRowCount" );
        exit( -1 );
    }

    if ( mem[ 7 ] != 0xef && mem[ 6 ] != 0xbe ) {
        size = 8;
    }
    else if ( mem[ 7 ] == 0xef && mem[ 6 ] == 0xbe && mem[ 3 ] != 0xef && mem[ 2 ] != 0xbe ) {
        size = 4;
    }
    else {
        size = 0;
    }
Практически тоже самое что мы и обсуждали, так что мы заслужили пирожок 8)
Аватара пользователя
aissp
Маньяк
Сообщения: 2710
Зарегистрирован: 07 ноя 2005, 09:51

Re: UnixODBC realted question.

Сообщение aissp »

Мне чур с мясом :D
Ответить