Uploaded image for project: 'MariaDB Server'
  1. MariaDB Server
  2. MDEV-34755

GCC -Wstringop-truncation due to safe_strcpy()

Details

    Description

      MDEV-34266 removed a #pragma that would silence a GCC warning about possible missing NUL terminator when invoking strncpy(). It looks like the warning depends on some optimization settings.

      Initially I thought that the warning got smarter in GCC 14, which was recently made the default compiler in Debian Sid, but I found examples of the warnings in the build logs also with GCC 12.2.0.

      Attachments

        Issue Links

          Activity

            Here is an example of a warning from GCC 14.2.0:

            10.6 2e580dc2a8da4aaf3a7f1b3cfb4f897dbb5f7089

            In file included from /mariadb/10.6/sql/sql_plugin.h:33,
                             from /mariadb/10.6/sql/mysqld.h:22,
                             from /mariadb/10.6/sql/semisync.h:21,
                             from /mariadb/10.6/sql/semisync_master.h:22,
                             from /mariadb/10.6/sql/semisync_master.cc:20:
            /mariadb/10.6/include/m_string.h: In member function ‘int Repl_semi_sync_master::report_binlog_update(THD*, THD*, const char*, my_off_t)’:
            /mariadb/10.6/include/m_string.h:260:10: warning: ‘char* __builtin_strncpy(char*, const char*, long unsigned int)’ specified bound 512 equals destination size [-Wstringop-truncation]
              260 |   strncpy(dst, src, dst_size);
                  |          ^
            

            I tried to fix it with the following patch:

            diff --git a/include/m_string.h b/include/m_string.h
            index 0cd6ff4513e..f9b8656623d 100644
            --- a/include/m_string.h
            +++ b/include/m_string.h
            @@ -249,6 +249,7 @@ static inline void lex_string_set3(LEX_CSTRING *lex_str, const char *c_str,
             static inline void safe_strcpy(char *dst, size_t dst_size, const char *src)
             {
               DBUG_ASSERT(dst_size > 0);
            +  dst_size--;
             
               /* 1) IF there is a 0 byte in the first dst_size bytes of src, strncpy will
                *    0-terminate dst, and pad dst with additional 0 bytes out to dst_size.
            @@ -258,7 +259,7 @@ static inline void safe_strcpy(char *dst, size_t dst_size, const char *src)
                */
             
               strncpy(dst, src, dst_size);
            -  dst[dst_size - 1]= 0;
            +  dst[dst_size]= 0;
             }
             
             /**
            

            This would result in another type of warning elsewhere, which I guess would also be output by some older versions of GCC:

            10.6 2e580dc2a8da4aaf3a7f1b3cfb4f897dbb5f7089 with patch

            In file included from /mariadb/10.6/include/my_bitmap.h:22,
                             from /mariadb/10.6/sql/log_event.h:36,
                             from /mariadb/10.6/sql/rpl_parallel.h:4,
                             from /mariadb/10.6/sql/rpl_parallel.cc:2:
            /mariadb/10.6/include/m_string.h: In function ‘int rpt_handle_event(rpl_parallel_thread::queued_event*, rpl_parallel_thread*)’:
            /mariadb/10.6/include/m_string.h:261:10: warning: ‘char* __builtin_strncpy(char*, const char*, long unsigned int)’ output may be truncated copying 511 bytes from a string of length 511 [-Wstringop-truncation]
              261 |   strncpy(dst, src, dst_size);
                  |          ^
            /mariadb/10.6/include/m_string.h:261:10: warning: ‘char* __builtin_strncpy(char*, const char*, long unsigned int)’ output may be truncated copying 511 bytes from a string of length 511 [-Wstringop-truncation]
            /mariadb/10.6/include/m_string.h: In member function ‘rpl_parallel_thread::queued_event* rpl_parallel_thread::get_qev(Log_event*, ulonglong, Relay_log_info*)’:
            /mariadb/10.6/include/m_string.h:261:10: warning: ‘char* __builtin_strncpy(char*, const char*, long unsigned int)’ output may be truncated copying 511 bytes from a string of length 511 [-Wstringop-truncation]
            /mariadb/10.6/include/m_string.h:261:10: warning: ‘char* __builtin_strncpy(char*, const char*, long unsigned int)’ output may be truncated copying 511 bytes from a string of length 511 [-Wstringop-truncation]
            /mariadb/10.6/include/m_string.h: In member function ‘rpl_parallel_thread::queued_event* rpl_parallel_thread::retry_get_qev(Log_event*, queued_event*, const char*, ulonglong, ulonglong)’:
            /mariadb/10.6/include/m_string.h:261:10: warning: ‘char* __builtin_strncpy(char*, const char*, long unsigned int)’ output may be truncated copying 511 bytes from a string of length 511 [-Wstringop-truncation]
            /mariadb/10.6/include/m_string.h: In function ‘void* handle_rpl_parallel_thread(void*)’:
            /mariadb/10.6/include/m_string.h:261:10: warning: ‘char* __builtin_strncpy(char*, const char*, long unsigned int)’ output may be truncated copying 511 bytes from a string of length 511 [-Wstringop-truncation]
            

            The 511 would likely be FN_REFLEN-1.

            It looks like the #pragma must be reinstated to keep GCC 14 happy.

            marko Marko Mäkelä added a comment - Here is an example of a warning from GCC 14.2.0: 10.6 2e580dc2a8da4aaf3a7f1b3cfb4f897dbb5f7089 In file included from /mariadb/10.6/sql/sql_plugin.h:33, from /mariadb/10.6/sql/mysqld.h:22, from /mariadb/10.6/sql/semisync.h:21, from /mariadb/10.6/sql/semisync_master.h:22, from /mariadb/10.6/sql/semisync_master.cc:20: /mariadb/10.6/include/m_string.h: In member function ‘int Repl_semi_sync_master::report_binlog_update(THD*, THD*, const char*, my_off_t)’: /mariadb/10.6/include/m_string.h:260:10: warning: ‘char* __builtin_strncpy(char*, const char*, long unsigned int)’ specified bound 512 equals destination size [-Wstringop-truncation] 260 | strncpy(dst, src, dst_size); | ^ I tried to fix it with the following patch: diff --git a/include/m_string.h b/include/m_string.h index 0cd6ff4513e..f9b8656623d 100644 --- a/include/m_string.h +++ b/include/m_string.h @@ -249,6 +249,7 @@ static inline void lex_string_set3(LEX_CSTRING *lex_str, const char *c_str, static inline void safe_strcpy(char *dst, size_t dst_size, const char *src) { DBUG_ASSERT(dst_size > 0); + dst_size--; /* 1) IF there is a 0 byte in the first dst_size bytes of src, strncpy will * 0-terminate dst, and pad dst with additional 0 bytes out to dst_size. @@ -258,7 +259,7 @@ static inline void safe_strcpy(char *dst, size_t dst_size, const char *src) */ strncpy(dst, src, dst_size); - dst[dst_size - 1]= 0; + dst[dst_size]= 0; } /** This would result in another type of warning elsewhere, which I guess would also be output by some older versions of GCC: 10.6 2e580dc2a8da4aaf3a7f1b3cfb4f897dbb5f7089 with patch In file included from /mariadb/10.6/include/my_bitmap.h:22, from /mariadb/10.6/sql/log_event.h:36, from /mariadb/10.6/sql/rpl_parallel.h:4, from /mariadb/10.6/sql/rpl_parallel.cc:2: /mariadb/10.6/include/m_string.h: In function ‘int rpt_handle_event(rpl_parallel_thread::queued_event*, rpl_parallel_thread*)’: /mariadb/10.6/include/m_string.h:261:10: warning: ‘char* __builtin_strncpy(char*, const char*, long unsigned int)’ output may be truncated copying 511 bytes from a string of length 511 [-Wstringop-truncation] 261 | strncpy(dst, src, dst_size); | ^ /mariadb/10.6/include/m_string.h:261:10: warning: ‘char* __builtin_strncpy(char*, const char*, long unsigned int)’ output may be truncated copying 511 bytes from a string of length 511 [-Wstringop-truncation] /mariadb/10.6/include/m_string.h: In member function ‘rpl_parallel_thread::queued_event* rpl_parallel_thread::get_qev(Log_event*, ulonglong, Relay_log_info*)’: /mariadb/10.6/include/m_string.h:261:10: warning: ‘char* __builtin_strncpy(char*, const char*, long unsigned int)’ output may be truncated copying 511 bytes from a string of length 511 [-Wstringop-truncation] /mariadb/10.6/include/m_string.h:261:10: warning: ‘char* __builtin_strncpy(char*, const char*, long unsigned int)’ output may be truncated copying 511 bytes from a string of length 511 [-Wstringop-truncation] /mariadb/10.6/include/m_string.h: In member function ‘rpl_parallel_thread::queued_event* rpl_parallel_thread::retry_get_qev(Log_event*, queued_event*, const char*, ulonglong, ulonglong)’: /mariadb/10.6/include/m_string.h:261:10: warning: ‘char* __builtin_strncpy(char*, const char*, long unsigned int)’ output may be truncated copying 511 bytes from a string of length 511 [-Wstringop-truncation] /mariadb/10.6/include/m_string.h: In function ‘void* handle_rpl_parallel_thread(void*)’: /mariadb/10.6/include/m_string.h:261:10: warning: ‘char* __builtin_strncpy(char*, const char*, long unsigned int)’ output may be truncated copying 511 bytes from a string of length 511 [-Wstringop-truncation] The 511 would likely be FN_REFLEN-1 . It looks like the #pragma must be reinstated to keep GCC 14 happy.

            People

              marko Marko Mäkelä
              marko Marko Mäkelä
              Votes:
              0 Vote for this issue
              Watchers:
              1 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved:

                Git Integration

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