Uploaded image for project: 'MariaDB Connector/C'
  1. MariaDB Connector/C
  2. CONC-810

mysql_escape_string segfault when compiled with -DDEFAULT_CHARSET="utf8"

    XMLWordPrintable

Details

    • Bug
    • Status: Open (View Workflow)
    • Major
    • Resolution: Unresolved
    • 3.4
    • 3.4
    • None
    • None

    Description

      https://mariadb.com/docs/connectors/mariadb-connector-c/api-functions/mysql_escape_string is documented as deprecated and it's probably not a good idea to build with default charset utf8 nowadays, but since this is a segfault it seemed better to report anyway.

      This was observed with python mysqlclient https://github.com/PyMySQL/mysqlclient/blob/v2.2.8/src/MySQLdb/_mysql.c#L1099 and a custom build (slapos) of mariadb 11.8.6 .

      A minimal reproduction can be something like this:

       
      #include <stdio.h>
      #include <string.h>
      #include <mysql.h>
       
      int main(void) {
          if (mysql_library_init(0, NULL, NULL)) {
              fprintf(stderr, "mysql_library_init failed\n");
              return 1;
          }
       
          const char *input = "hello 'world'";
          unsigned long input_len = strlen(input);
          char output[input_len * 2 + 1];
       
          unsigned long out_len = mysql_escape_string(output, input, input_len);
          printf("Result: \"%s\" (len=%lu)\n", output, out_len);
       
          mysql_library_end();
          return 0;
      }
      
      

      I used LLM to generate an explanation and a possible fix, it gave me the comment below, it might be completely wrong or it might be useful, I don't know mariadb internals and history to evaluate of this makes sense.

       
      /* 
       * Segfault reproducer for mysql_escape_string in MariaDB >= 10.6.1.
       *
       * MDEV-8334 (commit 2f7230c6 in libmariadb, 2fdb556e045 in server) renamed
       * the compiled charset csname from "utf8" to "utf8mb3" and added a compat
       * mapping in mysql_find_charset_name(), but not in mysql_get_charset_by_name().
       *
       * When the server build sets DEFAULT_CHARSET="utf8", mysql_once_init() calls
       * set_default_charset_by_name("utf8") which uses mysql_get_charset_by_name().
       * The strict strcmp("utf8", "utf8mb3") fails, so ma_default_charset_info stays
       * NULL. mysql_once_init() ignores this error and mysql_library_init() returns
       * success. Any subsequent call to mysql_escape_string() passes the NULL
       * charset pointer to mysql_cset_escape_slashes(), causing a segfault.
       *
       * Fix: in libmariadb/libmariadb/mariadb_charset.c, change
       * set_default_charset_by_name() to use mysql_find_charset_name() (which
       * already maps "utf8" -> "utf8mb3") instead of mysql_get_charset_by_name().
       */
      

      Attachments

        Activity

          People

            georg Georg Richter
            perrinjerome Jérome Perrin
            Votes:
            1 Vote for this issue
            Watchers:
            4 Start watching this issue

            Dates

              Created:
              Updated:

              Git Integration

                Error rendering 'com.xiplink.jira.git.jira_git_plugin:git-issue-webpanel'. Please contact your Jira administrators.