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

rpm scriptlet chown command dangerous

Details

    • Bug
    • Status: Closed (View Workflow)
    • Critical
    • Resolution: Fixed
    • 10.0.0, 5.5.28a
    • 10.0.2, 5.5.30
    • None
    • CentOS 5 , and CentOS 6

    Description

      If a machine where MariaDB server RPM is installed contains my.cnf with values that are not valid for the current version of the server, the installation process fails to detect correct values of basedir and datadir, ends up with datadir=/ and changes ownership of the entire system to mysql:mysql. For details about the fragment of the post-install script see the original description below.

      It can especially easily happen on a downgrade, but crossgrade and even upgrade can cause it too, if the problematic value was either deprecated and removed, or just became invalid due to different server build options or configuration (e.g. different character sets).

      Reproducible on MariaDB 5.5.28a and 10.0.0. Installation of 5.1-5.3 doesn't seem to have the disastrous effect, and neither does MySQL 5.5.29.

      My suggestion is to check whether mysqld help produced any results for basedir and datadir, and if not, abort further process since the installation obviously doesn't work as expected.

      Please also consider a request for an additional sanity check in the comment.

      ======================

      Original description

      The MariaDB-Server RPM appears to contain a flawed method of determining mysql 'datadir' path.

      This is in the post-install scriptlet packaged in the RPM for both the centos5 and centos6 versions, and both 64bit and 32bit packages.

      Relevant part of the post-installation shell scriptlet:

      mysql_dirs=(`/usr/sbin/mysqld --verbose --help 2>/dev/null|sed -ne 's/^\(basedir\|datadir\)[[:space:]]*\(.*\)$/\2/p'`)
      basedir="${mysql_dirs[0]}"
      datadir="${mysql_dirs[1]}"
        # datadir may be relative to a basedir!
      if expr $datadir : / > /dev/null; then
        mysql_datadir=$datadir
      else
        mysql_datadir=$basedir/$datadir
      fi

      In my testing, the initial shell array, $mysql_dirs is empty when that command is run. Thus mysql_datadir="/"

      This is dangerous because the subsequent use of the variable is:

      chown -R mysql:mysql $mysql_datadir

      On the centos6 server, moving /etc/my.cnf to /etc/my.cnf.TMP ahead of time, makes the initial population of $mysql_dirs[@] to be correct. (not sure why yet)

      On the centos5 server it's the same deal, however, moving the my.cnf causes the array to populate, but it still produces incorrect path values:

      mysql_dirs[0] => .
      mysql_dirs[1] => /

      I don't have a suggestion at the moment for how to fix, although I believe there must be a better way to find the mysql datadir than the current implementation.

      I hope this is the right place to submit this bug. I marked it critical because chowning the entire filesystem mysql:mysql recursively is fairly catasthropic.

      Attachments

        Issue Links

          Activity

            One root of the problem is that the script is using mysqld --help --verbose to get the options. The reason is that this may fail if there are some wrong commands/variables in my.cnf

            A better way is to use 'my_print_defaults mysqld mariadb server client-server'.

            This is what scripts like mysqld_safe uses.

            We could of course also add a check that the values are reasonable.

            • BASEDIR/libexec/mysqld or BASEDIR/sbin/mysqld should exists
            • DATADIR should not exists or the directory DATADIR/mysql should exists
            monty Michael Widenius added a comment - One root of the problem is that the script is using mysqld --help --verbose to get the options. The reason is that this may fail if there are some wrong commands/variables in my.cnf A better way is to use 'my_print_defaults mysqld mariadb server client-server'. This is what scripts like mysqld_safe uses. We could of course also add a check that the values are reasonable. BASEDIR/libexec/mysqld or BASEDIR/sbin/mysqld should exists DATADIR should not exists or the directory DATADIR/mysql should exists
            serg Sergei Golubchik added a comment - elenst so shall I push that? http://lists.askmonty.org/pipermail/commits/2013-March/004372.html

            Yes, please. I'll test an RPM from buildbot when it's baked.

            (I tried to imitate buildbot by patching manually and building my own RPM on CentOS 5, same way buildbot does, using "cmake . -DBUILD_CONFIG=mysql_release -DRPM=centos5", but it turned out not that easy as it requires a higher version of cmake than CentOS 5 has)

            elenst Elena Stepanova added a comment - Yes, please. I'll test an RPM from buildbot when it's baked. (I tried to imitate buildbot by patching manually and building my own RPM on CentOS 5, same way buildbot does, using "cmake . -DBUILD_CONFIG=mysql_release -DRPM=centos5", but it turned out not that easy as it requires a higher version of cmake than CentOS 5 has)

            Checked a manual RPM build on Fedora 17 64-bit, made from 5.5-serg revno 3685, source package prepared by buildbot (could not use an RPM baked by buildbot since it's not in archives [yet]).

            1) Installation of the package with broken my.cnf didn't cause the previous disaster. It still fails, of course (DB initialization doesn't work since mysqld cannot start), but the problem is fixable after installation by re-running mysql_install_db manually.
            2) Installation of the package in normal conditions went okay.
            3) Installation of the package with non-default basedir in my.cnf doesn't go too well (DB initialization doesn't work), but it's the same on old and new packages, so it's irrelevant. The problem is fixable the same way as in (1).

            One thing that comes to mind with these tests is that it's probably not right when yum installation exits with code 0 even although something went very wrong on the way; so, it's easy to miss the problem, and then it's very confusing when the fresh MariaDB installation turns out to be broken.
            But I'm not sure if it depends on us, and in any case it's out of scope of this bug.

            elenst Elena Stepanova added a comment - Checked a manual RPM build on Fedora 17 64-bit, made from 5.5-serg revno 3685, source package prepared by buildbot (could not use an RPM baked by buildbot since it's not in archives [yet] ). 1) Installation of the package with broken my.cnf didn't cause the previous disaster. It still fails, of course (DB initialization doesn't work since mysqld cannot start), but the problem is fixable after installation by re-running mysql_install_db manually. 2) Installation of the package in normal conditions went okay. 3) Installation of the package with non-default basedir in my.cnf doesn't go too well (DB initialization doesn't work), but it's the same on old and new packages, so it's irrelevant. The problem is fixable the same way as in (1). One thing that comes to mind with these tests is that it's probably not right when yum installation exits with code 0 even although something went very wrong on the way; so, it's easy to miss the problem, and then it's very confusing when the fresh MariaDB installation turns out to be broken. But I'm not sure if it depends on us, and in any case it's out of scope of this bug.

            pushed in 5.5

            serg Sergei Golubchik added a comment - pushed in 5.5

            People

              serg Sergei Golubchik
              kevinquinnyo Kevin Quinn
              Votes:
              0 Vote for this issue
              Watchers:
              6 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.