Type cast error in rlm_sql_unixodbc?

Plaggenmarsch, Erik Erik.Plaggenmarsch at atosorigin.com
Tue Aug 28 15:37:05 CEST 2007


Hi all,

We are running FreeRADIUS 1.1.6 on Solaris 10 (sparc) and want to
retrieve authorization information from an Pervasive SQL database via an
ODBC Bridge.
In order to do so we installed on our Solaris host:
- the unixODBC ODBC Manager 2.2.12
- Easysoft ODBC-ODBC Client 32bit for Solaris

But every time a RADIUS request was processed and a valid SQL query was
send via module rlm_sql_unixodb to the SQL database, both RADIUS and the
remote ODBC server crashed. Error in radiusd: memory allocation.

It took quite some debugging to find the cause of this. In the driver
rlm_sql_unixodbc, in file sql_unixodbc.c we found the following code:

===============
static int sql_num_fields(SQLSOCK *sqlsocket, SQL_CONFIG *config) {
    rlm_sql_unixodbc_sock *unixodbc_sock = sqlsocket->conn;
    long err_handle;
    int num_fields = 0;

    err_handle =
SQLNumResultCols(unixodbc_sock->stmt_handle,(SQLSMALLINT *)&num_fields);
    if (sql_state(err_handle, sqlsocket, config))
        return -1;

    return num_fields;
}
===============

SQLSMALLINT is defined in unixODBC, file: include/sqltypes.h

typedef signed short int   SQLSMALLINT;

But num_fields is of type 'int' !

This caused the function to return 0x20000 instead of 0x001, which in
turn caused both the radiusd and the remote ODBC server to allocate
memory for 0x20000 (131072) rows!

I simply changed this piece of code to:

===============
static int sql_num_fields(SQLSOCK *sqlsocket, SQL_CONFIG *config) {
    rlm_sql_unixodbc_sock *unixodbc_sock = sqlsocket->conn;
    long err_handle;
    SQLSMALLINT num_fields = 0;

    err_handle =
SQLNumResultCols(unixodbc_sock->stmt_handle,&num_fields);
    if (sql_state(err_handle, sqlsocket, config))
        return -1;

    return num_fields;
}
===============

This solved our crashes.

So the solution only involved changing the type of num_fields to
SQLSMALLINT (the same as required by the SQL call SQLNumResultCols) and
removing the type cast in the actual call to SQLNumResultCols
(unnecessary now).

After we solved it this way, I found the same error fixed in a similar
way on a SUSE distribution list:
http://lists.opensuse.org/opensuse-commit/2007-05/msg00099.html

I believe this to be a small error in the rlm_sql_unixodbc Driver.
Hopefully other people can benefit from our experience.

Can anyone confirm that my solution is correct and should work for all
OS's (as I expect) even though this might not cause problems on all OS's
(as on some, a short int is just as big a normal int)? Then I will send
in a bugreport via the site.

Kind regards,

Erik Plaggenmarsch

-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: disclaimer.txt
URL: <http://lists.freeradius.org/pipermail/freeradius-users/attachments/20070828/30a8efc2/attachment.txt>


More information about the Freeradius-Users mailing list