削除できないようにシンボリックリンクをロックするにはどうすればよいですか?
通常のファイル/ディレクトリchattr +i /file/location
はこれを実現できますが、シンボリックリンクを使用すると、chattr: Operation not supported while reading flags on my-file
。
同様の質問があります、 `/etc/resolv.conf`? に `chattr + i`を設定する方法ですが、解決策がありませんここで適用されます。
これは解決策を提供しませんが、chattr
がシンボリックリンクを不変にできない理由を説明します。
Linuxでは、不変属性は、FS_IOC_SETFLAGS
ioctl
を使用して制御される一連のフラグの一部です。歴史的にこれはext2で最初に実装され、chattr
自体はまだe2fsprogs
の一部です。 フラグを取得する を試行すると、フラグを設定する前に、chattr
は、処理するファイルが通常のファイルまたはディレクトリであることを明示的に確認します。
if (!lstat(name, &buf) &&
!S_ISREG(buf.st_mode) && !S_ISDIR(buf.st_mode)) {
goto notsupp;
}
これらのチェックを削除するか、シンボリックリンクも許可するように変更することは、chattr
がシンボリックリンクを不変にすることを許可するための良い最初のステップであると考えるかもしれませんが、次のハードルはその直後に発生します。
fd = open (name, OPEN_FLAGS);
if (fd == -1)
return -1;
r = ioctl (fd, EXT2_IOC_GETFLAGS, &f);
ioctl
はファイル記述子を操作します。つまり、フラグを設定する前にターゲットを開く必要があります。シンボリックリンクを開いてioctl
で使用することはできません。 open
はシンボリックリンクでO_NOFOLLOW
およびO_NOPATH
をサポートしますが、前者はそれ自体でELOOP
で失敗し、後者はaを返しますioctl
では使用できないファイル記述子。
chattrはシンボリックリンクではサポートされていませんが、バインドマウントを使用して削除できないリンクを作成できます。
ディレクトリの場合:
$ mkdir a b
$ echo a>a/ok
$ Sudo mount --bind a b
$ cat b/ok
a
$ rmdir b
rmdir: failed to remove 'b': Device or resource busy
そしてファイルの場合:
$ mkdir c d
$ echo c>c/ok
$ echo d>d/ok
$ Sudo mount --bind c/ok d/ok
$ cat d/ok
c
$ rm d/ok
rm: cannot remove 'd/ok': Device or resource busy
コメントできないので:
chattrは、chmod、fchmod()またはfchmodat()syscalls、またはioctl(シンボリックリンクについては何も言及されていません)のいずれかを使用している可能性が高いです。現在、どちらが見つかりませんか。ここでUbuntuのmanページを使用すると、一部変更されている可能性があります。
Chmodのmanページから:
chmodがシンボリックリンクのアクセス許可を変更することはありません。 chmodシステムコールは、権限を変更できません。シンボリックリンクのアクセス許可は決して使用されないため、これは問題ではありません。ただし、コマンドラインにリストされたシンボリックリンクごとに、chmodはポイントされたファイルの権限を変更します。対照的に、chmodは再帰的なディレクトリトラバーサル中に遭遇したシンボリックリンクを無視します。
Fchmod、chmodおよびfchmodat syscallのマンページを見ると、どれもそれを実装していません。 Chmod-ingはパスを逆参照するだけで、fchmodat()システムコールはAT_SYMLINK_NOFOLLOWを実装していません。
AT_SYMLINK_NOFOLLOW pathnameがシンボリックリンクの場合、逆参照しないでください。代わりにリンク自体を操作します。このフラグは現在実装されていません。