rmdirは空のディレクトリを削除できません

rmdirは空のディレクトリを削除できません

空のディレクトリの削除に問題があります。 strace にエラーが表示されます。

rmdir("empty_dir") = -1 ENOTEMPTY (Directory not empty)

何もls -la empty_dir表示されません。だから私はdebugfsを使ってfs(ext4)に接続し、このディレクトリにある隠しファイルを見ます。

# ls -lia empty_dir/
total 8
44574010 drwxr-xr-x 2 2686 2681 4096 Jan 13 17:59 .
44573990 drwxr-xr-x 3 2686 2681 4096 Jan 13 18:36 ..

debugfs:  ls empty_dir
 44574010  (12) .    44573990  (316) ..  
 26808797  (3768) _-----------------------------------------------------------.jpg  

なぜこれが起こるのですか?ファイルシステムをアンマウントし、完全に確認せずにこの問題を解決できますか?

追加情報:

「隠し」ファイルは、画像ビューアで開くことができる一般的なjpgファイルです。

debugfs:  dump empty_dir/_-----------------------------------------------------------.jpg /root/hidden_file

# file /root/hidden_file 
/root/hidden_file: JPEG image data, JFIF standard 1.02

rm -rf empty_dir同じエラーは利用できません:

unlinkat(AT_FDCWD, "empty_dir", AT_REMOVEDIR) = -1 ENOTEMPTY (Directory not empty)

find empty_dir/ -inum 26808797何も表示されません。

ベストアンサー1

私は追跡しlsてより多くの情報を得ました(重要ではないシステムコールを削除しました)。

open("empty_dir", O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC) = 3
getdents(3, /* 3 entries */, 32768)     = 80
write(1, ".\n", 2.)                     = 2
write(1, "..\n", 3..)                   = 3

まあ、私たちはシステムコールがgetdentsうまく機能し、3つのエントリ( '.'、 '..'、および'------*')をすべて返しますが、 '. ls'そして「..」だけが記録されていることを確認してください。これはgetdentscoreutilsが使用するラッパーに問題があることを意味します。 coreutilsはreaddirこれを処理するためにglibcラッパーを使用します。また、問題なくgetdentsのサンプルセクションで小さなプログラムをテストしたことをgetdents証明します。getdents男性ページ。プログラムはすべてのファイルを表示します。

たぶん私たちはglibcでバグを見つけましたか?だからglibcパッケージをディストリビューションの最新バージョンに更新しましたが、良い結果が得られませんでした。また、bugzillaで関連情報を見つけることができませんでした。

それでは、もう少し詳しく見てみましょう。

# gdb ls
(gdb) break readdir
(gdb) run
Breakpoint 1, 0x00007ffff7dfa820 in readdir () from /lib64/libncom.so.4.0.1
(gdb) info symbol readdir
readdir in section .text of /lib64/libncom.so.4.0.1

何を待つ? libncom.so.4.0.1? libcではありませんか?はい、悪意のあるアクティビティを隠すために使用されたlibc関数を含む悪意のある共有ライブラリを見ました。

# LD_PRELOAD=/lib64/libc.so.6 find / > good_find
# find / > injected_find
# diff good_find injected_find
10310d10305
< /lib64/libncom.so.4.0.1
73306d73300
< /usr/bin/_-config
73508d73501
< /usr/bin/_-pud
73714d73706
< /usr/bin/_-minerd
86854d86845
< /etc/ld.so.preload

ルートキットファイルの削除、すべてのパッケージファイルの確認(私のrpm -Va場合)、自動起動スクリプト、プリロード/プレリンク設定、システムファイル(私の場合はfind /+)、影響を受けるパスワードの変更、ルートキットプロセスの検索と終了:rpm -qf

# for i in /proc/[1-9]*; do name=$(</proc/${i##*/}/comm); ps -p ${i##*/} > /dev/null || echo $name; done
_-minerd

最後に、システム全体のアップデートを実行して再起動して問題を解決します。成功した破損の理由:ipmiインターフェイスには、公衆ネットワークで突然使用できる非常に古いファームウェアがあります。

おすすめ記事