web-dev-qa-db-ja.com

ファイルアクセス:あるプログラムではオープンが失敗し、別のプログラムでは失敗しない

これは最も珍しいことです。別のmy.cnfでmysqldを起動しようとしています(そのため、2つのMySQLデーモンを競合なしで実行できます)。ファイルは/etc/mysql/my2.cnfですが、mysqlはそれを開きません。

このコマンドを実行すると:

Sudo -u mysql strace /usr/sbin/mysqld --defaults-file=/etc/mysql/my2.cnf

私はこれを出力に表示します:

stat("/etc/mysql/my2.cnf", {st_mode=S_IFREG|0644, st_size=3574, ...}) = 0
open("/etc/mysql/my2.cnf", O_RDONLY)    = -1 EACCES (Permission denied)

ただし、コマンドを次のように変更すると、

Sudo -u mysql strace cat /etc/mysql/my2.cnf > /dev/null

私はこれを出力に表示します:

fstat(1, {st_mode=S_IFCHR|0666, st_rdev=makedev(1, 3), ...}) = 0
open("/etc/mysql/my2.cnf", O_RDONLY)    = 3

同じユーザー-同じカーネル呼び出し-異なる結果!

私はファイルのアクセス許可をチェックしました-そして拡張されたアクセス許可:

# ls -l $PWD/my2.cnf
-rw-r--r-- 1 root root 3574 2011-07-08 10:04 /etc/mysql/my2.cnf
# lsattr $PWD/my2.cnf
-----------------e- /etc/mysql/my2.cnf

AppArmourやSELinuxの一部に噛み付いていますか?ログにそのようなものは何も見つかりませんでした(daemon.log、syslog、またはメッセージを含む)。

この問題を解決するにはどうすればよいですか?

5
Mei

誰も答えていないので、私が見つけたものを教えます。

要するに問題は次のとおりです。catがファイル/etc/mysql/my2.cnfにアクセスすると、次のようになります。

open("/etc/mysql/my2.cnf", O_RDONLY)    = 3

ただし、mysqldが同じ呼び出しを行うと、別の答えが返されます。

open("/etc/mysql/my2.cnf", O_RDONLY)    = -1 EACCES (Permission denied)

したがって、答えはカーネルにありました。カーネルの何かがopen(2)の呼び出しをcatmysqldで区別していました。頭に浮かんだのはAppArmorだけでした。

システム上のパッケージを検索すると、AppArmorに関連するいくつかのものが見つかりました。パッケージ内のファイルを一覧表示すると、コマンドapparmor_statusが表示されます。これを実行すると、mysqldが実際にAppArmorでカバーされていることがわかりました。

# apparmor_status
apparmor module is loaded.
6 profiles are loaded.
6 profiles are in enforce mode.
   /sbin/dhclient3
   /usr/lib/NetworkManager/nm-dhcp-client.action
   /usr/lib/connman/scripts/dhclient-script
   /usr/sbin/mysqld
   /usr/sbin/ntpd
   /usr/sbin/tcpdump
0 profiles are in complain mode.
3 processes have profiles defined.
3 processes are in enforce mode :
   /usr/sbin/mysqld (22699) 
   /usr/sbin/mysqld (6808) 
   /usr/sbin/ntpd (2800) 
0 processes are in complain mode.
0 processes are unconfined but have a profile defined.

Apparmor(7)のマニュアルページを読むと、プロファイルが/etc/apparmor.dに保存されていることがわかりました。このディレクトリを見ると、ファイルusr.sbin.mysqldが表示されます。これは、変更するファイルであることがわかります。

ファイルの変更は簡単で、元の標準ディレクトリとファイルのエントリをコピーして、新しいディレクトリとファイルにします。これが完了したら、service apparmor restartを使用して新しい構成をアクティブ化します。

「Appitor」からの「監査」に関するメッセージをsyslogで確認したことはありません。これは、メッセージがsyslogまたはmessagesではなく/var/log/audit/audit.logに送信されたためです。このファイルには、次のようなエントリが含まれています。

type=APPARMOR_DENIED msg=audit(1310141055.025:256):  operation="mknod" pid=28765 parent=28764 profile="/usr/sbin/mysqld" requested_mask="c::" de
nied_mask="c::" fsuid=104 ouid=104 name="/var/log/mysql2/error.log"
type=APPARMOR_DENIED msg=audit(1310141055.025:257):  operation="open" pid=28765 parent=28764 profile="/usr/sbin/mysqld" requested_mask="r::" den
ied_mask="r::" fsuid=104 ouid=104 name="/var/lib/mysql2/mysql/plugin.frm"
type=APPARMOR_DENIED msg=audit(1310141055.035:258):  operation="open" pid=28765 parent=28764 profile="/usr/sbin/mysqld" requested_mask="rw::" de
nied_mask="rw::" fsuid=104 ouid=104 name="/var/lib/mysql2/ibdata1"
type=APPARMOR_DENIED msg=audit(1310141097.085:259):  operation="open" pid=28780 parent=28779 profile="/usr/sbin/mysqld" requested_mask="::r" den
ied_mask="::r" fsuid=104 ouid=0 name="/etc/mysql/my2.cnf"
type=APPARMOR_DENIED msg=audit(1310141177.636:260):  operation="open" pid=28841 parent=28840 profile="/usr/sbin/mysqld" requested_mask="::r" den
ied_mask="::r" fsuid=104 ouid=0 name="/etc/mysql/my2.cnf"
type=APPARMOR_DENIED msg=audit(1310141614.953:261):  operation="open" pid=28903 parent=28902 profile="/usr/sbin/mysqld" requested_mask="::r" denied_mask="::r" fsuid=104 ouid=0 name="/etc/mysql/my2.cnf"
type=APPARMOR_DENIED msg=audit(1310141665.113:262):  operation="open" pid=28916 parent=28915 profile="/usr/sbin/mysqld" requested_mask="::r" denied_mask="::r" fsuid=104 ouid=0 name="/etc/mysql/my2.cnf"
type=APPARMOR_DENIED msg=audit(1310141739.863:263):  operation="open" pid=28926 parent=28925 profile="/usr/sbin/mysqld" requested_mask="::r" denied_mask="::r" fsuid=104 ouid=0 name="/etc/mysql/my2.cnf"
type=APPARMOR_DENIED msg=audit(1310142253.323:264):  operation="open" pid=28962 parent=19377 profile="/usr/sbin/mysqld" requested_mask="::r" denied_mask="::r" fsuid=104 ouid=0 name="/etc/mysql/conf2.d/"

これは私の推論と調査を証明します。AppArmorはopen(2)リクエストを拒否していました。

何を探すべきかわかったので、これに関連するブログエントリを見つけました- 2008年のずっと前の記事

4
Mei