2017年1月19日木曜日

最近のPercona Serverで/usr/local/mysqlにシンボリックリンクを張ったら上手く起動しないでござる

バイナリー.tar.gz版のはなし。


こんな風に/usr/local/mysqlじゃないところにPercona Serverをダウンロードして、/usr/local/mysqlにシンボリックリンクを張る。

$ cd /usr/local
$ wget https://www.percona.com/downloads/Percona-Server-5.7/Percona-Server-5.7.16-10/binary/tarball/Percona-Server-5.7.16-10-Linux.x86_64.ssl101.tar.gz
$ tar xf Percona-Server-5.7.16-10-Linux.x86_64.ssl101.tar.gz
$ ln -s Percona-Server-5.7.16-10-Linux.x86_64.ssl101 mysql
$ ll
total 234348
drwxr-xr-x  2 root root        18 Jun  8  2016 bin
drwxr-xr-x  2 root root         6 Sep 23  2011 etc
drwxr-xr-x  2 root root         6 Sep 23  2011 games
drwxr-xr-x  2 root root         6 Sep 23  2011 include
drwxr-xr-x  2 root root         6 Sep 23  2011 lib
drwxr-xr-x  3 root root        18 Jun  8  2016 lib64
drwxr-xr-x  2 root root         6 Sep 23  2011 libexec
lrwxrwxrwx  1 root root        44 Jan 19 11:47 mysql -> Percona-Server-5.7.16-10-Linux.x86_64.ssl101
drwxr-xr-x 11 root root      4096 Jan 19 11:48 Percona-Server-5.7.16-10-Linux.x86_64.ssl101
-rw-r--r--  1 root root 239966730 Nov 28 05:07 Percona-Server-5.7.16-10-Linux.x86_64.ssl101.tar.gz
drwxr-xr-x  2 root root         6 Sep 23  2011 sbin
drwxr-xr-x  6 root root        58 Jun  8  2016 share
drwxr-xr-x  2 root root         6 Sep 23  2011 src


で、イニシャライズして起動しようとすると転ける。

$ useradd mysql
$ cd mysql
$ bin/mysqld --no-defaults --initialize --datadir=./data --user=mysql
$ bin/mysqld_safe --no-defaults --datadir=./data --user=mysql
 mysqld_safe Adding '/usr/local/Percona-Server-5.7.16-10-Linux.x86_64.ssl101/lib/mysql/libjemalloc.so.1' to LD_PRELOAD for mysqld
 mysqld_safe ld_preload libraries can only be loaded from system directories (/usr/lib64, /usr/lib, /usr/local/mysql/lib)


Percona Serverはもともと(特にインストールしてなければ) $MY_BASEDIR_VERSION/lib/libjemalloc.so.1 をロードして勝手にjemallocを使ってくれるようになっている けれど、CVE-2016-6662 対策で 変なところからLD_PRELOADできないようにmysqld_safeに修正 が入っている。

ちなみに本家5.7.16は オプションをパースする時にバリデーション してるだけだけど、Percona Serverは「デフォルトで勝手にjemallocをロードする」ために、 LD_PRELOADをセットする手前でもう一回バリデーション している。


 288 add_mysqld_ld_preload() {
 289   lib_to_add="$1"
 290   lib_to_add=$(readlink -f $lib_to_add)
 291   log_notice "Adding '$lib_to_add' to LD_PRELOAD for mysqld"
 292
 293   # Check if the library is in the reduced number of standard system directories
 294   case "$lib_to_add" in
 295     /usr/lib64/* | /usr/lib/* | ${MY_BASEDIR_VERSION}/lib/*)
 296       ;;
 297     *)
 298       log_error "ld_preload libraries can only be loaded from system directories (/usr/lib64, /usr/lib, ${MY_BASEDIR_VERSION}/lib)"
 299       exit 1
 300       ;;
 301   esac

290行目 のreadlinkが肝で、自動でロードしようとした /usr/local/mysql/lib/libjemalloc.so.1 をシンボリックリンク展開して /usr/local/Percona-Server-5.7.16-10-Linux.x86_64.ssl101/lib/mysql/libjemalloc.so.1 にしてしまい、結果 $MYSQL_BASEDIR_VERSION/lib ディレクトリーの外側だから不正、NG! となってる。

取り敢えずこの行をコメントアウトすれば動かせるようにはなる。
ただしその場合リアルにlibjemalloc.so.1をシンボリックリンクで変な共有ライブラリーに置き換えられると死ぬ。

…けど、そんなところ置き換えられるような権限取られたらもっとひどいことされてるだろうから大丈夫だとは思う。野良ビルドでなければ。


5.7.16でしか確認していないけど、CVE-2016-6662対応以降 のマイナーバージョンであれば5.5, 5.6も同じことが起こるかも知れない。

0 件のコメント :

コメントを投稿