Bug #16144 mysql_stmt_attr_get type error
Submitted: 3 Jan 2006 1:38 Modified: 2 Feb 2006 4:27
Reporter: Eric Huss (Candidate Quality Contributor) Email Updates:
Status: Closed Impact on me:
None 
Category:MySQL Server Severity:S3 (Non-critical)
Version:5.1 OS:Linux (Linux, FreeBSD i386)
Assigned to: Konstantin Osipov CPU Architecture:Any

[3 Jan 2006 1:38] Eric Huss
Description:
The documentation indicates that the STMT_ATTR_UPDATE_MAX_LENGTH attribute is a my_bool type.  However, mysql_stmt_attr_get assumes it is an unsigned long.  If you attempt to call mysql_stmt_attr_get passing in a pointer to a my_bool object defined on the stack, this can cause potential stack corruption (possibly leading to a segmentation fault).

How to repeat:
The following demonstrates stack corruption:

#include <stdio.h>
#include <mysql.h>

main()
{
unsigned long value;
void * other_p;
my_bool flag;
void * flag_p;
MYSQL * mysql;
MYSQL_STMT * stmt;

value = 7;

flag_p = &flag;
other_p = &value;

mysql = mysql_init(NULL);
stmt = mysql_stmt_init(mysql);

printf("flag=%p other=%p\n", flag_p, other_p);
mysql_stmt_attr_get(stmt, STMT_ATTR_UPDATE_MAX_LENGTH, &flag);
printf("flag=%p other=%p\n", flag_p, other_p);

printf("%i\n", flag);
}

On my platform, this displays:
flag=0xbfbff817 other=0xbfbff81c
flag=0xbfbff817 other=0xbf000000
0

Notice how (due to byte ordering), the other_p value gets stomped on.

Suggested fix:
Either change mysql_stmt_attr_get for STMT_ATTR_UPDATE_MAX_LENGTH to:

*(my_bool*) value= stmt->update_max_length;

or clarify the documentation that the data types for mysql_stmt_attr_get are not the same as mysql_stmt_attr_set.  Currently it says: "If the option is an integer, then arg should point to the value of the integer."  This leads one to believe that you should pass in a pointer to an integer *only if* the argument should be an integer which in this case it is not.
[11 Jan 2006 15:44] Valeriy Kravchuk
Thank you for a bug report. Verified just as described on 5.0.19-BK (ChangeSet@1.2020.3.1, 2006-01-10 13:44:08+02:00) on Linux:

[openxs@Fedora 5.0]$ gcc -o 16144 `$CFG --cflags` 16144.c `$CFG --libs`
[openxs@Fedora 5.0]$ ./16144
flag=0xbfe9bd2f other=0xbfe9bd34
flag=0xbfe9bd2f other=0xbf000000
0
[openxs@Fedora 5.0]$ uname -a
Linux Fedora 2.4.22-1.2115.nptl #1 Wed Oct 29 15:42:51 EST 2003 i686 i686 i386 GNU/Linux
[17 Jan 2006 20:19] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/1218
[17 Jan 2006 21:26] Konstantin Osipov
Fixed in 4.1.17, merged into 5.0.19
[2 Feb 2006 4:27] Mike Hillyer
Documented in 4.1.17 and 5.0.19 changelogs:

   <listitem>
        <para>
          The <function>mysql_stmt_attr_get</function> function returned
          an unsigned int instead of a boolean for
          <literal>STMT_ATTR_UPDATE_MAX_LENGTH</literal>. (Bug #16144)
        </para>
      </listitem>
[4 Mar 2006 19:35] Konstantin Osipov
The patch for this bug breaks binary compatibility and will be reverted in 4.1 and 5.0 release series. It will be kept in 5.1 and up.
[4 Mar 2006 20:05] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/3469
[4 Mar 2006 21:39] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/3472