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

The code in TABLE_SHARE::init_from_binary_frm_image() is not safe

Details

    Description

      The code in TABLE_SHARE::init_from_binary_frm_image() is not safe for broken FRM files.

      In debug mode it can crash on assert.
      In release mode its behavior is not predictable.

      interval_nr=  (uint) strpos[12];
      ...
      DBUG_ASSERT(interval_nr); // Expect non-null expression
      ...
      vcol_info_length= interval_nr;
      vcol_expr_length= vcol_info_length -
                                (uint)(FRM_VCOL_OLD_HEADER_SIZE(opt_interval_id));
      ...
      
      

      The same problem presents in the branch for MYSQL57_GENERATED_FIELD (since 10.2), it's reported as a separate issue MDEV-16518.

      Attachments

        Issue Links

          Activity

            bar Alexander Barkov created issue -
            bar Alexander Barkov made changes -
            Field Original Value New Value
            bar Alexander Barkov made changes -
            Description The code in TABLE_SHARE::init_from_binary_frm_image() is not safe for broken FRM files.

            In debug mode it can crash of assert.
            In release mode its behavior is not predictable.

            {code:cpp}
            interval_nr= (uint) strpos[12];
            ...
            DBUG_ASSERT(interval_nr); // Expect non-null expression
            ...
            vcol_info_length= interval_nr;
            vcol_expr_length= vcol_info_length -
                                      (uint)(FRM_VCOL_OLD_HEADER_SIZE(opt_interval_id));
            ...

            {code}


            The same problem presents in the branch for MYSQL57_GENERATED_FIELD:
            {code:cpp}
            vcol_info_length= uint2korr(vcol_screen_pos + 1);
            ...
            DBUG_ASSERT(vcol_info_length)
            ...
            vcol_screen_pos+= vcol_info_length + MYSQL57_GCOL_HEADER_SIZE;;
            {code}
            The code in TABLE_SHARE::init_from_binary_frm_image() is not safe for broken FRM files.

            In debug mode it can crash of assert.
            In release mode its behavior is not predictable.

            {code:cpp}
            interval_nr= (uint) strpos[12];
            ...
            DBUG_ASSERT(interval_nr); // Expect non-null expression
            ...
            vcol_info_length= interval_nr;
            vcol_expr_length= vcol_info_length -
                                      (uint)(FRM_VCOL_OLD_HEADER_SIZE(opt_interval_id));
            ...

            {code}


            The same problem presents in the branch for MYSQL57_GENERATED_FIELD:
            {code:cpp}
            vcol_info_length= uint2korr(vcol_screen_pos + 1);
            ...
            DBUG_ASSERT(vcol_info_length);
            ...
            vcol_screen_pos+= vcol_info_length + MYSQL57_GCOL_HEADER_SIZE;
            {code}
            bar Alexander Barkov made changes -
            Affects Version/s 10.2 [ 14601 ]
            Affects Version/s 10.3 [ 22126 ]
            Affects Version/s 10.1 [ 16100 ]
            bar Alexander Barkov made changes -
            Affects Version/s 5.5 [ 15800 ]
            bar Alexander Barkov made changes -
            Fix Version/s 10.2 [ 14601 ]
            Fix Version/s 10.3 [ 22126 ]
            Fix Version/s 5.5 [ 15800 ]
            Fix Version/s 10.0 [ 16000 ]
            Fix Version/s 10.1 [ 16100 ]
            bar Alexander Barkov made changes -
            Affects Version/s 10.0 [ 16000 ]
            bar Alexander Barkov made changes -
            Attachment t1.frm [ 45769 ]

            To reproduce the problem, put the attached f1.frm into the MariaDB data directory and run:

            TRUNCATE TABLE t1;
            

            It crashes with the following output:

            mysqld: /home/bar/maria-git/server.5.5/sql/table.cc:1465: int open_binary_frm(THD*, TABLE_SHARE*, uchar*, File): Assertion `interval_nr' failed.
             
            Program received signal SIGABRT, Aborted.
            [Switching to Thread 0x7ffff7f81700 (LWP 8869)]
            0x00007ffff670ba28 in __GI_raise (sig=sig@entry=6)
                at ../sysdeps/unix/sysv/linux/raise.c:55
            55	  return INLINE_SYSCALL (tgkill, 3, pid, selftid, sig);
            

            bar Alexander Barkov added a comment - To reproduce the problem, put the attached f1.frm into the MariaDB data directory and run: TRUNCATE TABLE t1; It crashes with the following output: mysqld: /home/bar/maria-git/server.5.5/sql/table.cc:1465: int open_binary_frm(THD*, TABLE_SHARE*, uchar*, File): Assertion `interval_nr' failed.   Program received signal SIGABRT, Aborted. [Switching to Thread 0x7ffff7f81700 (LWP 8869)] 0x00007ffff670ba28 in __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:55 55 return INLINE_SYSCALL (tgkill, 3, pid, selftid, sig);
            bar Alexander Barkov made changes -
            Status Open [ 1 ] In Progress [ 3 ]
            bar Alexander Barkov made changes -
            Description The code in TABLE_SHARE::init_from_binary_frm_image() is not safe for broken FRM files.

            In debug mode it can crash of assert.
            In release mode its behavior is not predictable.

            {code:cpp}
            interval_nr= (uint) strpos[12];
            ...
            DBUG_ASSERT(interval_nr); // Expect non-null expression
            ...
            vcol_info_length= interval_nr;
            vcol_expr_length= vcol_info_length -
                                      (uint)(FRM_VCOL_OLD_HEADER_SIZE(opt_interval_id));
            ...

            {code}


            The same problem presents in the branch for MYSQL57_GENERATED_FIELD:
            {code:cpp}
            vcol_info_length= uint2korr(vcol_screen_pos + 1);
            ...
            DBUG_ASSERT(vcol_info_length);
            ...
            vcol_screen_pos+= vcol_info_length + MYSQL57_GCOL_HEADER_SIZE;
            {code}
            The code in TABLE_SHARE::init_from_binary_frm_image() is not safe for broken FRM files.

            In debug mode it can crash of assert.
            In release mode its behavior is not predictable.

            {code:cpp}
            interval_nr= (uint) strpos[12];
            ...
            DBUG_ASSERT(interval_nr); // Expect non-null expression
            ...
            vcol_info_length= interval_nr;
            vcol_expr_length= vcol_info_length -
                                      (uint)(FRM_VCOL_OLD_HEADER_SIZE(opt_interval_id));
            ...

            {code}


            The same problem presents in the branch for MYSQL57_GENERATED_FIELD (since 10.2):
            {code:cpp}
            vcol_info_length= uint2korr(vcol_screen_pos + 1);
            ...
            DBUG_ASSERT(vcol_info_length);
            ...
            vcol_screen_pos+= vcol_info_length + MYSQL57_GCOL_HEADER_SIZE;
            {code}
            bar Alexander Barkov made changes -
            bar Alexander Barkov made changes -
            Description The code in TABLE_SHARE::init_from_binary_frm_image() is not safe for broken FRM files.

            In debug mode it can crash of assert.
            In release mode its behavior is not predictable.

            {code:cpp}
            interval_nr= (uint) strpos[12];
            ...
            DBUG_ASSERT(interval_nr); // Expect non-null expression
            ...
            vcol_info_length= interval_nr;
            vcol_expr_length= vcol_info_length -
                                      (uint)(FRM_VCOL_OLD_HEADER_SIZE(opt_interval_id));
            ...

            {code}


            The same problem presents in the branch for MYSQL57_GENERATED_FIELD (since 10.2):
            {code:cpp}
            vcol_info_length= uint2korr(vcol_screen_pos + 1);
            ...
            DBUG_ASSERT(vcol_info_length);
            ...
            vcol_screen_pos+= vcol_info_length + MYSQL57_GCOL_HEADER_SIZE;
            {code}
            The code in TABLE_SHARE::init_from_binary_frm_image() is not safe for broken FRM files.

            In debug mode it can crash of assert.
            In release mode its behavior is not predictable.

            {code:cpp}
            interval_nr= (uint) strpos[12];
            ...
            DBUG_ASSERT(interval_nr); // Expect non-null expression
            ...
            vcol_info_length= interval_nr;
            vcol_expr_length= vcol_info_length -
                                      (uint)(FRM_VCOL_OLD_HEADER_SIZE(opt_interval_id));
            ...

            {code}


            The same problem presents in the branch for MYSQL57_GENERATED_FIELD (since 10.2), it's reported as a separate issue MDEV-16518.
            bar Alexander Barkov made changes -
            Description The code in TABLE_SHARE::init_from_binary_frm_image() is not safe for broken FRM files.

            In debug mode it can crash of assert.
            In release mode its behavior is not predictable.

            {code:cpp}
            interval_nr= (uint) strpos[12];
            ...
            DBUG_ASSERT(interval_nr); // Expect non-null expression
            ...
            vcol_info_length= interval_nr;
            vcol_expr_length= vcol_info_length -
                                      (uint)(FRM_VCOL_OLD_HEADER_SIZE(opt_interval_id));
            ...

            {code}


            The same problem presents in the branch for MYSQL57_GENERATED_FIELD (since 10.2), it's reported as a separate issue MDEV-16518.
            The code in TABLE_SHARE::init_from_binary_frm_image() is not safe for broken FRM files.

            In debug mode it can crash on assert.
            In release mode its behavior is not predictable.

            {code:cpp}
            interval_nr= (uint) strpos[12];
            ...
            DBUG_ASSERT(interval_nr); // Expect non-null expression
            ...
            vcol_info_length= interval_nr;
            vcol_expr_length= vcol_info_length -
                                      (uint)(FRM_VCOL_OLD_HEADER_SIZE(opt_interval_id));
            ...

            {code}


            The same problem presents in the branch for MYSQL57_GENERATED_FIELD (since 10.2), it's reported as a separate issue MDEV-16518.
            bar Alexander Barkov made changes -
            issue.field.resolutiondate 2018-06-19 09:03:57.0 2018-06-19 09:03:57.004
            bar Alexander Barkov made changes -
            Component/s Virtual Columns [ 10803 ]
            Fix Version/s 5.5.61 [ 22914 ]
            Fix Version/s 10.0.36 [ 22916 ]
            Fix Version/s 10.1.35 [ 23116 ]
            Fix Version/s 10.2.16 [ 23110 ]
            Fix Version/s 10.3.8 [ 23113 ]
            Fix Version/s 10.4.0 [ 23115 ]
            Fix Version/s 10.2 [ 14601 ]
            Fix Version/s 5.5 [ 15800 ]
            Fix Version/s 10.0 [ 16000 ]
            Fix Version/s 10.1 [ 16100 ]
            Fix Version/s 10.3 [ 22126 ]
            Resolution Fixed [ 1 ]
            Status In Progress [ 3 ] Closed [ 6 ]
            serg Sergei Golubchik made changes -
            Workflow MariaDB v3 [ 86462 ] MariaDB v4 [ 154134 ]

            People

              bar Alexander Barkov
              bar Alexander Barkov
              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.