scriptがPermission deniedになるとき、必要なのは多くの場合ownerへexecute bitを追加することで、chmod 777ではありません。file自身だけでなく、親directoryをtraverseできるexecute permission、filesystemのnoexec mount、shebang interpreterの存在も確認します。
結論は「statでownerと現在modeを読み、必要userだけにchmod u+xを付与します。変更前後のsymbolic/octal modeとhashを記録し、group共有が必要な場合だけowner/group設計を行います」です。
Permission deniedを四種類に分ける
regular fileのx bitはexecute許可、directoryのx bitはentryへのtraverseを意味します。scriptを./tool.shで起動するにはfile x、親directory traverse、shebang先interpreterへのaccessが必要です。bash tool.shならBashがfileをreadするためx bitは不要ですがread permissionが必要です。
- statで見たfile owner・group・mode
- 実行するuserと必要な共有範囲
- 親directory各階層のtraverse permission
- mount optionにnoexecがないか
- shebangのinterpreter pathとline ending
Permission deniedのcommand、full path、user ID、mount pointを記録します。ls -lの一行だけでなくstatのnumeric modeを保存します。ACLがある場合はmode bitだけでeffective accessを断定しません。network filesystemやcontainer bind mountはhost側policyも確認します。
実行できないときはls -lとstatでmode、owner、groupを確認し、namei -lで親ディレクトリに検索権限があるかを見ます。fileとheadでshebang、mountでnoexecの有無、getfaclで追加ACLを確認します。「Permission denied」は実行bit不足だけでなく、親directory、noexec mount、SELinux/AppArmor、interpreter不在でも起きます。chmodを行う前にどの主体へ実行を許すかを決めます。
最小のexecute bitだけを追加する
source管理下のscript hashを確認し、owner実行だけならchmod u+xを使用します。teamで実行するならgroup ownerとg+xを検討し、otherへxを広げません。変更後は一般userで無害なsampleを実行し、write permissionが不要に増えていないことを確認します。
現在modeを確認
stat --format='%n owner=%U group=%G mode=%a symbolic=%A' -- ./tool.sh
変更前のowner/group/modeを作業記録へ残します。
ownerへexecuteだけ追加
chmod u+x -- ./tool.sh
read/writeやgroup/otherのpermissionを変えないsymbolic modeです。
group実行を追加
chmod g+x -- ./team-tool.sh
group membershipとdirectory permissionを確認した承認済み共有scriptに限定します。
親directoryを確認
namei -l -- ./scripts/tool.sh
利用可能な環境では各path componentのowner/modeを読み、勝手に変更しません。
mount optionを確認
findmnt -T ./tool.sh -o TARGET,SOURCE,FSTYPE,OPTIONS
noexecならchmodだけでは直接実行できず、mount policy ownerへ確認します。
所有者だけへ実行を追加するならchmod u+x — script.shのようなsymbolic modeを使い、既存のread/write bitを保ちます。group運用なら所有groupとmembershipを確認してg+xを検討し、o+xを安易に付けません。repositoryで配布するスクリプトはGitのexecutable bitも確認します。実行権限を追加してもshebangや内容が安全になるわけではないため、bash -nとレビューを先に行います。
read・write・execute bitをfile・directory・mount別に理解する
chmod u+xはcurrent owner classへexecute bitを足し、既存read/write bitを保持します。chmod 755は全modeを固定するため、元のgroup writeや特殊bitを意図せず変えることがあります。noexec mountはfilesystem policyで直接executionを抑えますが、interpreterへfileを渡す挙動をsecurity boundaryとして過信しません。
- regular fileのx bitはそのclassによるexecutionを許可する
- directoryのx bitはpath traversalを許可する
- chmod symbolic modeは指定bitだけを変更できる
- bash script.shはexecute bitでなくread permissionを使う
- noexec mountではchmod後もdirect executionが拒否される場合がある
Linuxでは通常ファイルのexecute bit、各親directoryのexecute/search bit、filesystemのmount option、interpreterへのアクセスが実行可否へ関係します。chmod 755はownerにrwx、groupとothersにr-xを一括設定するため、既存modeを意図せず変えます。bash script.shはファイルをBashの入力として読むためexecute bit不要ですが、noexec制約の回避手段として無条件に使うべきではありません。
777を避けownerとgroupを設計する
chmod 777、recursive chmod、owner変更をquick fixにしません。setuid/setgid bitやACLがあるfileはsecurity ownerへ確認します。download scriptへxを付ける前にsource、signature/hash、内容をreviewします。productionでroot-owned scriptを一般user writableにしません。
- Permission deniedへchmod 777を使う
- fileだけ見て親directoryのx bitを見ない
- chmod 755で既存mode全部を上書きする
- noexec mountをpermission bitの問題とする
- execute bit付与をscript安全性の確認と混同する
chmod -R 777、filesystem全体への再帰変更、system directoryのmode変更を行いません。書き込み可能なスクリプトへ実行権限を広く付けると、内容を書き換えられて任意commandを実行されます。ownerと書き込み主体を先に確認し、rootで動くcronやserviceのスクリプトは一般利用者が変更できない場所へ置きます。会社のnoexec方針をinterpreter直接起動で迂回しません。
権限変更後の実行testを行う
対象userで./tool.shの無害なhelp/sampleを実行し、exit statusを確認します。statでmode、owner、group、ACL、hashを再取得し、group/otherへ不要なwriteやexecuteが増えていないことを確認します。
- Permission deniedのlayerをfile・directory・mount・interpreterへ分類した
- 必要なuser/classだけへx bitを追加した
- 元のowner・group・read/write permissionを保った
- target userのsample実行とstatusを確認した
statで変更前後のoctal modeとowner/groupを比較し、対象ユーザーとしてtest fixtureで一度実行します。親directory、symlink実体、interpreter path、noexec mountを再確認し、exit statusとログを見ます。groupへ許可した場合は新しいlogin sessionでgroup membershipを確認します。権限を戻す必要があるときは記録した元modeへchmodで戻し、再度statします。
execute bitを付ける必要性を判断する
一回だけ内容を見るならbash script.shで足り、fileへxを付けない選択もあります。shared operational toolならgroupとdeployment processを設計します。noexecやACLがsecurity policyなら回避せずownerへ申請します。
個人スクリプトならu+x、共同管理なら専用groupとg+x、実行を許さないdata fileならbitを付けないという最小権限を選びます。packageやsystemd unitが管理するファイルは手作業chmodではなくpackage・configuration managementで修正します。noexecやmandatory access controlが原因なら、単なる権限エラーとして迂回せず、管理者へ対象pathとpolicy denialを提示します。

コメント