2013年12月3日火曜日

メモ:com.apple.quarantine 拡張属性

調べきれてないけど回避策を見つけたのでメモ。

Mavericks に変えたせいか、今まで使ってたスクリプトが動かなくなった。こんな感じ:
$ cat hello
#!/bin/sh
echo hello
$ ./hello
-bash: ./hello: /bin/sh: bad interpreter: Operation not permitted
$
以下の場合にこれが起きるようだ。
  • 実行ファイルに com.apple.quarantine 拡張属性がついていて、その最初の値の下から3ビット目(0x4)がオンであるか、
  • そのファイルが内在するスパースバンドル(マウントされている)の *.sparsebundle/token に com.apple.quarantine 拡張属性がついていて、0x4がオンである
後者は、.dmg の場合は分からない。

確認法。ls -l@ でそのファイルを見て、「com.apple.quarantine 数字」という表示が出るかを見る。
$ ls -l@ hello
-rwxr-xr-x@ 1 mkazuto  staff  21 12  2 18:00 hello*
        com.apple.quarantine    27
quarantine-test-local$
「数字」(ここでは27)は拡張属性の大きさ(バイト数)。中身を見るには xattr -l する:
$ xattr -l hello
com.apple.quarantine: 0006;xxxxxxxx;アプリ名;
$
セミコロンでいくつかの情報が区切られている。最初の値は16進数のようで、この値の0x4がオンだと冒頭のエラーが出る。ここでは0x0006なので0x4がオンだからエラーになる。2つ目の値は16進数で何かのIDぽい。3つ目の文字列は、このファイルを(たぶん作成すると同時に)検疫隔離 (quarantine) したアプリケーションのようだ。エラーが出たときに /var/log/system.log を見ると、
Dec  3 10:10:09 rMBP kernel[0]: exec of /Users/mkazuto/hello denied since it was quarantined by アプリ名 and created without user consent, qtn-flags was 0x00000006
のようなメッセージが残っている。

対処法。xattr -d を使って com.apple.quarantine 拡張属性を取り除けば、一応動く。
$ xattr -d com.apple.quarantine hello
あとは0x4ビットだけを落とすという手もある。
$ xattr -w com.apple.quarantine '2;xxxxxxxx;アプリ名;' hello
スパースバンドルの token ファイルの拡張属性はマウント時に確認されるようだ。変更を有効にするにはマウントし直す必要がある。

いずれにせよ、この拡張属性の意味を正確には知らないので、これで大丈夫かは不明。Chrome や Safari を使ってネットから落としたファイルを見ると、0001とか0002とか0006とか0041とかいろんな値がついている。

実行ファイルに直接 com.apple.quarantine 拡張属性がついてる場合の情報はネットに多かったが、スパースバンドル内にある実行ファイルの実行可否がスパースバンドルの token ファイルの拡張属性に影響されると気づくのに時間がかかった。